繁体   English   中英

GraphQL Spring 引导 Web 拦截器返回错误响应,如果标头不存在

[英]GraphQL Spring Boot Web Interceptor to return an error response if headers not present

我正在尝试创建将拦截所有/graphql请求的逻辑,检查标头是否存在并将它们添加到 MDC,如果不“拒绝”带有适当错误的请求。

第一次尝试是将其添加到已注册的AsyncHandlerInterceptor#preHandle中,我在其中抛出了IllegalArgumentException 不幸的是, DataFetcherExceptionResolverAdapter没有捡起它。 然后我尝试了一个WebInterceptor ,但解析器再次没有看到这个异常。

这是拦截器,我对反应很陌生,所以请不要判断大声笑。 当 header 存在时,它似乎可以正常工作,但在引发异常时却不行。

@Bean
public WebInterceptor headerInterceptor() {
    return (webInput, chain) ->
        chain.next(webInput)
            .doFirst(() -> {
                String header = webInput.getHeaders().getFirst("some-header");
                if (header != null && !header.isEmpty()) {
                    MDC.put("some-header", header);
                } else throw new IllegalArgumentException("...");
            })
            .doFinally(s -> MDC.clear());
}

拦截器代码(未到达):

public class SomeDataFetcherExceptionResolverAdapter extends DataFetcherExceptionResolverAdapter {

    @Override
    protected GraphQLError resolveToSingleError(Throwable throwable, DataFetchingEnvironment environment) {
        if (throwable instanceof ConstraintViolationException || throwable instanceof IllegalArgumentException) {
            return GraphqlErrorBuilder
                    .newError(environment)
                    .errorType(BAD_REQUEST)
                    .message(throwable.getMessage())
                    .build();
        } else {
            return super.resolveToSingleError(throwable, environment);
        }
    }
}

添加@ControllerAdvice

这对我有用

这就是我最终做的事情:

public class GraphqlHeaderInterceptor implements WebInterceptor {
...
    @Override
    public Mono<WebOutput> intercept(WebInput input, WebInterceptorChain chain) {
        return chain.next(input)
                .doFirst(() -> {
                     // fill MDC or throw Exception if no header
                })
                .onErrorResume(ex -> Mono.just(errResult(input, ex)))
                .doFinally(s -> MDC.clear());
    }

    private WebOutput errResult(WebInput input, Throwable ex) {
        var error = GraphqlErrorBuilder
            .newError()
            .errorType(BAD_REQUEST)
            .message(ex.getMessage())
            .build();

        var result = ExecutionResultImpl.newExecutionResult().addError(error).build();
        return new WebOutput(input, result);
    }
...
}

这对我来说已经足够好了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM