Openliberty 上的 Microprofile GraphQL 中的错误处理

问题描述 投票:0回答:1

我正在努力寻找正确的方法来处理服务层中抛出的异常,以便 GraphQL 响应包含有意义的错误消息。我知道服务器错误不应包含任何消息,但这里我们讨论的是客户端错误。

GPT 建议使用 JaxRS 中的

ExceptionMapper
但这不起作用:

@GraphQLApi
@RegisterProvider(MyExceptionMapper.class)
public class MembersGraphQLApi {

    @Query("members")
    public List<Member> members(String keyword) throws UserException {
        throw new UserException("This is a test exception");
    }
}

@Provider
public class MyExceptionMapper implements ExceptionMapper<UserException> {

    @Override
    public Response toResponse(UserException exception) {
        // just some dummy code to make the response very different
        // to the generated response
        return Response
                .status(400)
                .entity(exception.getMessage())
                .build();
    }

}

这是服务器自动生成的响应,我希望有所不同:

{
    "errors": [
        {
            "message": "Server Error",
            "locations": [
                {
                    "line": 2,
                    "column": 2
                }
            ],
            "path": [
                "members"
            ],
            "extensions": {
                "exception": "de.codevibe.jeelab.UserException",
                "classification": "DataFetchingException",
                "code": "user"
            }
        }
    ],
    "data": {
        "members": null
    }
}

到目前为止,我唯一的解决方案是捕获每个业务异常并重新抛出一些

GraphQLException
异常子类型,但这感觉很愚蠢,在每个查询方法中进行所有样板处理。

基本上我想要的是类似 Spring Boot 控制器建议的东西。

jakarta-ee graphql open-liberty
1个回答
0
投票

是的,GPT 幻想使用与 JAX-RS 相同的异常映射机制会很好。但这实际上甚至没有必要,因为错误响应的格式是在 GraphQL 规范中指定的,而这对于 REST 来说并非如此;所以 JAX-RS 一定更强大,而 GraphQL 更简单。

术语

client error
server error
通常没有明确的定义。在 MP GraphQL Spec 中,
client error
被定义为客户端发送技术上无效的请求,但您想要抛出的
UserException
可能是深度验证的结果,例如数据库中的某些数据不存在。根据上面的规范,这是一个
server error

默认情况下,未检查异常返回的

message
(默认情况下)始终为“服务器错误”,因此有关实际 Java 异常的详细信息不会泄露给客户端。但对于已检查的异常,消息会包含在内。所以你的
UserException
似乎没有被选中,这也很好:

您可以将异常类的完全限定名称

de.codevibe.jeelab.UserException
放入 MP Config
mp.graphql.showErrorMessage
(请注意,此选项的已弃用名称是
mp.graphql.exceptionsWhiteList
)。如果您有多个异常,您可以用逗号作为分隔符列出它们,甚至更好:您可以创建所有异常的公共超类,客户端应该了解它们做错了什么,并进行配置。

那就是

message
;而
code
中的
extensions
则源自类名,对此还有更多要说的。

© www.soinside.com 2019 - 2024. All rights reserved.