I am using Spring Webflux (3.2.2) and Spring Graphql(3.2.2) . I have implemented a WebGraphQlInterceptor which looks for a request header. If its not found , I am throwing a Custom Exception . I have defined a Controller Advice class which has a method to handle Custom Exception , but seems like control is not going to that advice method.
@ControllerAdvice
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
public class GraphQLExceptionHandler {
@GraphQlExceptionHandler(CustomException.class)
public GraphQLError handleCustomException(CustomException e) {
return GraphQLError.newError()
.errorType(resolve(e.errorCode))
.message(e.getMessage())
.build();
}
@GraphQlExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public GraphQLError handleException(Exception e) {
return GraphQLError.newError()
.errorType(ErrorType.INTERNAL_ERROR)
.message(e.getMessage())
.build();
}
@ExceptionHandler(CustomException.class)
public final Mono<ResponseEntity<Map<String, Object>>> handleCustomExceptions(CustomException ex,
ServerWebExchange exchange) {
log.info("Application Exception occurred : {} ", ex.getMessage());
ErrorDetails errorDetails = new ErrorDetails(ex.errorCode, ex.getMessage(), ex,
exchange.getRequest().getPath().value());
return Mono.just(ResponseEntity.status(HttpStatus.resolve(ex.errorCode)).body(formatError(errorDetails)));
}
/**
* Handle exceptions.
*
* @param ex the ex
* @param request the request
* @return the response entity
*/
@ResponseStatus(INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public final Mono<ResponseEntity<Map<String, Object>>> handleExceptions(Exception ex, ServerWebExchange exchange) {
log.error("Exception occurred : {0}", ex);
ErrorDetails errorDetails = new ErrorDetails(INTERNAL_SERVER_ERROR.value(),
"Something went wrong, please try again after sometime", ex, exchange.getRequest().getPath().value());
return Mono.just(ResponseEntity.status(INTERNAL_SERVER_ERROR).body(formatError(errorDetails)));
}
/**
* Format error.
*
* @param errorDetails the error details
* @return the map
*/
private Map<String, Object> formatError(ErrorDetails errorDetails) {
Map<String, Object> error = new HashMap<>();
error.put("errors", errorDetails);
return error;
}
private ErrorType resolve(int errorCode) {
return switch (errorCode) {
case 401 -> ErrorType.UNAUTHORIZED;
case 403 -> ErrorType.FORBIDDEN;
case 404 -> ErrorType.NOT_FOUND;
default -> ErrorType.INTERNAL_ERROR;
};
}
}
My Custom Interceptor
@Component
public class RequestHeaderInterceptor implements WebGraphQlInterceptor {
public static final String AUTHORIZATION_HEADER_KEY = "Authorization";
@NotNull
@Override
public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, Chain chain) {
String value = request.getHeaders().getFirst(AUTHORIZATION_HEADER_KEY);
if (value == null) {
throw new CustomException(ErrorMessage.AUTH_ID_NOT_FOUND);
}
request.configureExecutionInput((executionInput, builder) ->
builder.graphQLContext(Collections.singletonMap("authHeader", value)).build());
return chain.next(request);
}
}
What am I missing .