@@ -499,25 +499,27 @@ added by <<server.interception, WebGraphQlInterceptor>> components.
499
499
500
500
501
501
[[execution.exceptions]]
502
- === Exception Resolution
502
+ === Exceptions
503
503
504
- A GraphQL Java application can register a `DataFetcherExceptionHandler` to decide how to
505
- represent exceptions from the data layer in the "errors" section of the GraphQL response.
504
+ In GraphQL Java, `DataFetcherExceptionHandler` decides how to represent exceptions from
505
+ data fetching in the "errors" section of the response. An application can register a
506
+ single handler only.
506
507
507
- Spring for GraphQL has a built-in `DataFetcherExceptionHandler` that is configured for use
508
- by the default <<execution.graphqlsource>> builder. It allows applications to register
509
- one or more Spring `DataFetcherExceptionResolver` components that are invoked sequentially
510
- until one resolves the `Exception` to a (possibly empty) list of ` graphql.GraphQLError`
511
- objects .
508
+ Spring for GraphQL registers a `DataFetcherExceptionHandler` that provides default
509
+ handling and enables the `DataFetcherExceptionResolver` contract. An application can
510
+ register any number of resolvers via <<execution.graphqlsource>> builder and those are in
511
+ order until one them resolves the `Exception` to a `List< graphql.GraphQLError>`.
512
+ The Spring Boot starter detects beans of this type .
512
513
513
- `DataFetcherExceptionResolver` is an asynchronous contract. For most implementations, it
514
- would be sufficient to extend `DataFetcherExceptionResolverAdapter` and override
515
- one of its `resolveToSingleError` or `resolveToMultipleErrors` methods that
516
- resolve exceptions synchronously.
514
+ `DataFetcherExceptionResolverAdapter` is a convenient base class with protected methods
515
+ `resolveToSingleError` and `resolveToMultipleErrors`.
517
516
518
- A `GraphQLError` can be assigned to a category via `graphql.ErrorClassification`.
519
- In Spring GraphQL, you can also assign via `ErrorType` which has the following common
520
- classifications that applications can use to categorize errors:
517
+ The <<controllers>> programming model enables handling data fetching exceptions with
518
+ annotated exception handler methods with a flexible method signature, see
519
+ <<controllers.exception-handler>> for details.
520
+
521
+ A `GraphQLError` can be assigned to a category based on the GraphQL Java
522
+ `graphql.ErrorClassification`, or the Spring GraphQL `ErrorType`, which defines the following:
521
523
522
524
- `BAD_REQUEST`
523
525
- `UNAUTHORIZED`
@@ -534,6 +536,7 @@ error details.
534
536
Unresolved exception are logged at ERROR level along with the `executionId` to correlate
535
537
to the error sent to the client. Resolved exceptions are logged at DEBUG level.
536
538
539
+
537
540
[[execution.exceptions.request]]
538
541
==== Request Exceptions
539
542
@@ -1662,6 +1665,88 @@ Batch mapping methods can return:
1662
1665
1663
1666
1664
1667
1668
+ [[controllers.exception-handler]]
1669
+ === `@GraphQlExceptionHandler`
1670
+
1671
+ Use `@GraphQlExceptionHandler` methods to handle exceptions from data fetching with a
1672
+ flexible <<controllers.exception-handler.signature,method signature>>. When declared in a
1673
+ controller, exception handler methods apply to exceptions from the same controller:
1674
+
1675
+ [source,java,indent=0,subs="verbatim,quotes"]
1676
+ ----
1677
+ @Controller
1678
+ public class BookController {
1679
+
1680
+ @QueryMapping
1681
+ public Book bookById(@Argument Long id) {
1682
+ // ...
1683
+ }
1684
+
1685
+ @GraphQlExceptionHandler
1686
+ public GraphQLError handle(BindException ex) {
1687
+ return GraphQLError.newError().errorType(ErrorType.BAD_REQUEST).message("...").build();
1688
+ }
1689
+
1690
+ }
1691
+ ----
1692
+
1693
+ When declared in an `@ControllerAdvice`, exception handler methods apply across controllers:
1694
+
1695
+ [source,java,indent=0,subs="verbatim,quotes"]
1696
+ ----
1697
+ @ControllerAdvice
1698
+ public class GlobalExceptionHandler {
1699
+
1700
+ @GraphQlExceptionHandler
1701
+ public GraphQLError handle(BindException ex) {
1702
+ return GraphQLError.newError().errorType(ErrorType.BAD_REQUEST).message("...").build();
1703
+ }
1704
+
1705
+ }
1706
+ ----
1707
+
1708
+ Exception handling via `@GraphQlExceptionHandler` methods is applied automatically to
1709
+ controller invocations. To handle exceptions from other `graphql.schema.DataFetcher`
1710
+ implementations, not based on controller methods, obtain a
1711
+ `DataFetcherExceptionResolver` from `AnnotatedControllerConfigurer`, and register it in
1712
+ `GraphQlSource.Builder` as a <<execution.exceptions,DataFetcherExceptionResolver>>.
1713
+
1714
+
1715
+
1716
+
1717
+ [[controllers.exception-handler.signature]]
1718
+ ==== Method Signature
1719
+
1720
+ Exception handler methods support a flexible method signature with method arguments
1721
+ resolved from a `DataFetchingEnvironment,` and matching to those of
1722
+ <<controllers.schema-mapping.arguments,@SchemaMapping methods>>.
1723
+
1724
+ Supported return types are listed below:
1725
+
1726
+ [cols="1,2"]
1727
+ |===
1728
+ | Return Type | Description
1729
+
1730
+ | `graphql.GraphQLError`
1731
+ | Resolve the exception to a single field error.
1732
+
1733
+ | `Collection<GraphQLError>`
1734
+ | Resolve the exception to multiple field errors.
1735
+
1736
+ | `void`
1737
+ | Resolve the exception without response errors.
1738
+
1739
+ | `Object`
1740
+ | Resolve the exception to a single error, to multiple errors, or none.
1741
+ The return value must be `GraphQLError`, `Collection<GraphQLError>`, or `null`.
1742
+
1743
+ | `Mono<T>`
1744
+ | For asynchronous resolution where `<T>` is one of the supported, synchronous, return types.
1745
+
1746
+ |===
1747
+
1748
+
1749
+
1665
1750
1666
1751
[[security]]
1667
1752
== Security
0 commit comments