简体   繁体   English

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

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

I'm trying to create logic that will intercept all /graphql requests, check if headers are present and add them to MDC, and if not "reject" the request with an appropriate error.我正在尝试创建将拦截所有/graphql请求的逻辑,检查标头是否存在并将它们添加到 MDC,如果不“拒绝”带有适当错误的请求。

First attempt was to add it to a registered AsyncHandlerInterceptor#preHandle , where I threw an IllegalArgumentException .第一次尝试是将其添加到已注册的AsyncHandlerInterceptor#preHandle中,我在其中抛出了IllegalArgumentException Unfortunately, the DataFetcherExceptionResolverAdapter does not pick it up.不幸的是, DataFetcherExceptionResolverAdapter没有捡起它。 Then I tried aa WebInterceptor , but again the resolver doesn't see this exception.然后我尝试了一个WebInterceptor ,但解析器再次没有看到这个异常。

Here is the interceptor, I'm very new to reactive, so pls don't judge lol.这是拦截器,我对反应很陌生,所以请不要判断大声笑。 It seems to work correctly, when the header is present, but not when the exception is thrown.当 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());
}

Interceptor code (not reached):拦截器代码(未到达):

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

Add @ControllerAdvice添加@ControllerAdvice

This worked for me这对我有用

Here's what I ended up doing:这就是我最终做的事情:

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

Which is good enough for me.这对我来说已经足够好了。

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

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