繁体   English   中英

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

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

目前,我抛出RuntimeException来返回GraphQL验证错误。 它工作异常出色,但它会在我的日志中引发带有大堆栈跟踪的可怕错误。

在这里,您可以看到我正在检查提交的新用户注册突变,以确保密码彼此匹配并且电子邮件地址尚未使用。

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

我不清楚您要问的是什么...但是我假设您想自定义要记录的内容。

对于初学者,我建议使用像ValidationException这样的专用异常类型,您可以用不同的方式捕获和处理它。

至于日志记录,它可能发生在grapqh-java中,因为SPQR本身不会记录任何内容。 默认情况下,graphql-java使用SimpleDataFetcherExceptionHandler记录在字段解析期间捕获的异常

现在,您有两个选择,您可以在SPQR中注册一个ResolverInterceptor ,以捕获验证异常并记录所需的内容,并为用户返回带错误消息的DataFetcherResult 由于没有验证异常会冒充到graphql-java,因此DataFetcherExceptionHandler在这种情况下没有任何事可做。

它看起来像:

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

此处查看答案,以获取有关在Spring Boot中注册自定义拦截器的说明。

另一个选择是替换DataFetcherExceptionHandler graphql-java使用。 为此,您必须自己构造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();
}

如果某个地方有Spring功能可用于托管bean的异常处理,我也不会感到惊讶。

暂无
暂无

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

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