Apply context to all exception resolvers
This is more consistent with DataFetcher's, it less brittle, and a no-op where there is no ThreadLocal context.
This commit is contained in:
@@ -27,12 +27,9 @@ import reactor.core.publisher.Mono;
|
||||
* {@code GraphQLError}'s to add to the GraphQL response. Implementations are typically
|
||||
* declared as beans in Spring configuration and invoked in order until one emits a List.
|
||||
*
|
||||
* <p>
|
||||
* Use the {@link SingleErrorExceptionResolver} convenience adapter when you need to
|
||||
* resolve exceptions to a single {@code GraphQLError} only.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
* @see SyncDataFetcherExceptionResolver
|
||||
*/
|
||||
public interface DataFetcherExceptionResolver {
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class ExceptionResolversExceptionHandler implements DataFetcherExceptionHandler
|
||||
// https://github.com/graphql-java/graphql-java/issues/2356
|
||||
try {
|
||||
return Flux.fromIterable(this.resolvers)
|
||||
.flatMap((resolver) -> resolver.resolveException(ex, env))
|
||||
.flatMap((resolver) -> resolveErrors(ex, env, resolver))
|
||||
.next()
|
||||
.map((errors) -> DataFetcherExceptionHandlerResult.newResult().errors(errors).build())
|
||||
.switchIfEmpty(Mono.fromCallable(() -> applyDefaultHandling(ex, env)))
|
||||
@@ -89,6 +89,19 @@ class ExceptionResolversExceptionHandler implements DataFetcherExceptionHandler
|
||||
}
|
||||
}
|
||||
|
||||
private Mono<List<GraphQLError>> resolveErrors(
|
||||
Throwable ex, DataFetchingEnvironment environment, DataFetcherExceptionResolver resolver) {
|
||||
|
||||
ContextView contextView = ContextManager.getReactorContext(environment);
|
||||
try {
|
||||
ContextManager.restoreThreadLocalValues(contextView);
|
||||
return resolver.resolveException(ex, environment);
|
||||
}
|
||||
finally {
|
||||
ContextManager.resetThreadLocalValues(contextView);
|
||||
}
|
||||
}
|
||||
|
||||
private DataFetcherExceptionHandlerResult applyDefaultHandling(Throwable ex, DataFetchingEnvironment env) {
|
||||
GraphQLError error = GraphqlErrorBuilder.newError(env)
|
||||
.message(ex.getMessage())
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.List;
|
||||
import graphql.GraphQLError;
|
||||
import graphql.schema.DataFetchingEnvironment;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.context.ContextView;
|
||||
|
||||
/**
|
||||
* {@link DataFetcherExceptionResolver} that resolves exceptions synchronously.
|
||||
@@ -32,23 +31,16 @@ import reactor.util.context.ContextView;
|
||||
public interface SyncDataFetcherExceptionResolver extends DataFetcherExceptionResolver {
|
||||
|
||||
@Override
|
||||
default Mono<List<GraphQLError>> resolveException(Throwable exception, DataFetchingEnvironment environment) {
|
||||
ContextView contextView = ContextManager.getReactorContext(environment);
|
||||
try {
|
||||
ContextManager.restoreThreadLocalValues(contextView);
|
||||
return Mono.just(doResolveException(exception, environment));
|
||||
}
|
||||
finally {
|
||||
ContextManager.resetThreadLocalValues(contextView);
|
||||
}
|
||||
default Mono<List<GraphQLError>> resolveException(Throwable exception, DataFetchingEnvironment env) {
|
||||
return Mono.just(doResolveException(exception, env));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this method to resolve exceptions.
|
||||
* @param exception the exception to resolve
|
||||
* @param environment the environment for the invoked {@code DataFetcher}
|
||||
* @param env the environment for the invoked {@code DataFetcher}
|
||||
* @return the list of resolved GraphQL errors
|
||||
*/
|
||||
List<GraphQLError> doResolveException(Throwable exception, DataFetchingEnvironment environment);
|
||||
List<GraphQLError> doResolveException(Throwable exception, DataFetchingEnvironment env);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user