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:
Rossen Stoyanchev
2021-06-18 18:34:03 +01:00
parent efa585b887
commit cedb5fb40d
3 changed files with 19 additions and 17 deletions

View File

@@ -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 {

View File

@@ -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())

View File

@@ -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);
}