控制未传递到控制器建议类

问题描述 投票:0回答:1

我正在使用 Spring Webflux (3.2.2) 和 Spring Graphql(3.2.2) 。我已经实现了一个 WebGraphQlInterceptor 来查找请求标头。如果找不到,我将抛出自定义异常。我已经定义了一个控制器建议类,它有一个处理自定义异常的方法,但似乎控制不会转到该建议方法。

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

我的自定义拦截器

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

我错过了什么。

spring-boot spring-webflux spring-graphql
1个回答
0
投票

拦截器在数据获取器完成 GraphQL 查询之前就已介入。这意味着控制器级别的异常处理程序机制将不知道此异常,因为它发生在上游。

根据用例,您可以返回自定义 WebGraphQlResponse。这里涉及安全性,因此我将调用 Spring Security 并直接在 HTTP 级别执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.