简体   繁体   English

在GraphQL-SPQR中返回错误的正确方法

[英]Correct way to return errors in GraphQL-SPQR

At the moment, I'm throwing RuntimeException 's to return GraphQL validation errors. 目前,我抛出RuntimeException来返回GraphQL验证错误。 It works surprisingly well, with the exception that it throws horrible errors with large stack traces in my logs. 它工作异常出色,但它会在我的日志中引发带有大堆栈跟踪的可怕错误。

Here you can see I'm checking the submitted new user registration mutation to be sure the passwords match one another and the email address isn't already in use. 在这里,您可以看到我正在检查提交的新用户注册突变,以确保密码彼此匹配并且电子邮件地址尚未使用。

What is the correct way to do this in GraphQL SPQR Spring Boot Starter. 在GraphQL SPQR Spring Boot Starter中执行此操作的正确方法是什么。

@GraphQLMutation (name="register")
public User register(@GraphQLArgument(name="firstname") String firstname, @GraphQLArgument(name="lastname") String lastname, @GraphQLArgument(name="email") String email, @GraphQLArgument(name="msisdn") String msisdn, @GraphQLArgument(name="password") String password, @GraphQLArgument (name="confirmPassword") String confirmPassword) {
    if (userRepo.findByEmail(email) != null) {
        throw new RuntimeException("User already exists");
    }

    if (!password.equals(confirmPassword)) {
        throw new RuntimeException("Passwords do not match");
    }

    User newUser = new User();
    //...
    return userRepo.save(newUser);
}

It's unclear to me what you're asking... but I'll assume you want to customize what's getting logged. 我不清楚您要问的是什么...但是我假设您想自定义要记录的内容。

For starters, I'd suggest a dedicated exception type like ValidationException , that you can catch and handle differently. 对于初学者,我建议使用像ValidationException这样的专用异常类型,您可以用不同的方式捕获和处理它。

As for the logging, it's probably happening in grapqh-java as SPQR doesn't log anything by itself. 至于日志记录,它可能发生在grapqh-java中,因为SPQR本身不会记录任何内容。 By default graphql-java uses SimpleDataFetcherExceptionHandler which logs the exceptions caught during field resolution. 默认情况下,graphql-java使用SimpleDataFetcherExceptionHandler记录在字段解析期间捕获的异常

You now have a couple of options, you could register a ResolverInterceptor in SPQR that catches validation exceptions and logs what you want, and returns a DataFetcherResult with the error message for the user. 现在,您有两个选择,您可以在SPQR中注册一个ResolverInterceptor ,以捕获验证异常并记录所需的内容,并为用户返回带错误消息的DataFetcherResult Because no validation exceptions bubble up to graphql-java, DataFetcherExceptionHandler has nothing to do in this scenario. 由于没有验证异常会冒充到graphql-java,因此DataFetcherExceptionHandler在这种情况下没有任何事可做。

It would look something like: 它看起来像:

public class ValidationInterceptor implements ResolverInterceptor {

    @Override
    public Object aroundInvoke(InvocationContext context, Continuation continuation) throws Exception {
        try {
            return continuation.proceed(context);
        } catch (ValidationException e) {
            log.warning(e);
            return DataFetcherResult.newResult()
                    .error(GraphqlErrorBuilder
                            .newError(context.getResolutionEnvironment().dataFetchingEnvironment)
                            .message(e.getMessage()) //the message for the user
                            .build());
        }
    }
}

Look at the answer here for instructions on registering your custom interceptor with Spring Boot. 此处查看答案,以获取有关在Spring Boot中注册自定义拦截器的说明。

Another option would be to replace the DataFetcherExceptionHandler graphql-java uses. 另一个选择是替换DataFetcherExceptionHandler graphql-java使用。 To do that you must construct GraphQL object yourself and register it as a bean. 为此,您必须自己构造GraphQL对象并将其注册为Bean。

@Bean
public GraphQL graphQL(GraphQLSchema schema) {
    GraphQL.Builder builder = GraphQL.newGraphQL(schema)
            .queryExecutionStrategy(new AsyncExecutionStrategy(customExceptionHandler))
            .mutationExecutionStrategy(new AsyncSerialExecutionStrategy(customExceptionHandler));
    return builder.build();
}

I also wouldn't be surprised if there's a Spring feature somewhere that can be used for exception handling on managed beans. 如果某个地方有Spring功能可用于托管bean的异常处理,我也不会感到惊讶。

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

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