使用 graphql-java-tools 和 graphql-spring-boot-starter 处理错误
Posted
技术标签:
【中文标题】使用 graphql-java-tools 和 graphql-spring-boot-starter 处理错误【英文标题】:Error handling with graphql-java-tools and graphql-spring-boot-starter 【发布时间】:2020-09-16 23:14:36 【问题描述】:如何处理我的 graphQL API 中的错误?我正在使用 graphql-java-tools 和 graphql-spring-boot-starter。我创建了错误处理程序,但每次我得到响应 200,即使抛出异常也是如此。你能告诉我应该如何设置错误代码,例如 400 作为响应?
@Component
public class CustomGraphQLErrorHandler implements GraphQLErrorHandler
@Override
public List<GraphQLError> processErrors(List<GraphQLError> list)
return list.stream().map(this::getNested).collect(Collectors.toList());
private GraphQLError getNested(GraphQLError error)
if (error instanceof ExceptionWhileDataFetching)
ExceptionWhileDataFetching exceptionError = (ExceptionWhileDataFetching) error;
if (exceptionError.getException() instanceof GraphQLError)
return (GraphQLError) exceptionError.getException();
return error;
【问题讨论】:
【参考方案1】:GraphQL 服务器在可以接受请求时返回 HTTP 200(语法有效,服务器已启动...)。
如果发生错误,它会返回 200 并在响应中填写错误列表。
因此,在客户端,您将拥有:
技术服务器错误,如果 HTTP 状态不同于 200 如果 HTTP 处理请求(技术或非技术性)时出错 状态为 200 且错误列表不为空 如果 HTTP 没有错误 状态为 200 并且错误列表不存在(它不应该是 根据 GraphQL 规范,存在和空)【讨论】:
非常感谢艾蒂安。我认为它的工作原理与休息的情况相同,我们可以在响应实体中设置响应代码。【参考方案2】:您可以尝试在错误处理方法中抛出一些异常,例如
package my.company.graphql.error;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import graphql.GraphQLError;
import graphql.GraphQLException;
import graphql.servlet.core.GraphQLErrorHandler;
import graphql.validation.ValidationError;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class GraphQLErrorHandlerImpl implements GraphQLErrorHandler
@Override
public List<GraphQLError> processErrors(List<GraphQLError> graphQLErrors)
return graphQLErrors.stream().map(this::handleGraphQLError).collect(Collectors.toList());
private GraphQLError handleGraphQLError(GraphQLError error)
if (error instanceof GraphQLException)
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "GraphQLException as GraphQLError...", (GraphQLException) error);
else if (error instanceof ValidationError)
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ValidationError: " + error.getMessage());
else
log.error("Yet another GraphQLError...", error);
return error;
...除了您只会得到 400 状态代码,而在您的响应中仅此而已,因为 Spring 不是在这里处理抛出的异常,因为您正在与 GraphQL servlet(不是 Spring 的)在例如http://127.0.0.1:8080/graphql
只有在您的日志中,您才能看到堆栈跟踪:(这只是 GraphQL 查询中未使用片段的验证错误示例)
[2020-09-23 15:59:34.382]-[080-exec-2]-[INFO ]-[g.s.AbstractGraphQLHttpServlet]: Bad POST request: parsing failed
org.springframework.web.server.ResponseStatusException: 400 BAD_REQUEST "ValidationError: Validation error of type UnusedFragment: Unused fragment someUnusedFragment"
at my.company.graphql.error.GraphQLErrorHandlerImpl.handleGraphQLError(GraphQLErrorHandlerImpl.java:33) ~[classes/:na]
您可以引入更复杂的 GraphQL 错误处理,但这只是测试和试用(我们也已经做了很长一段时间了...)
【讨论】:
以上是关于使用 graphql-java-tools 和 graphql-spring-boot-starter 处理错误的主要内容,如果未能解决你的问题,请参考以下文章
graphql servlet 未使用 graphql-java-tools 启动(未找到模式文件?)
在 graphql-java-tools 中禁用 GraphQL Introspection
如何在 graphql-java-tools Resolver 中 @Autowire 一个 JPA 存储库