错误处理
通常 GraphQL 通过一个在 response 中的 errors
结构块,来支持错误报告。Responses 可以同时包含数据部分和错误部分,比如可以返回正确处理的字段数据和发生错误的字段信息。对应发生错误的字段将会被设置为 null,并且将会在 errors
结构块中添加错误信息。
DGS 框架有一个开箱即用的异常处理器,根据本页面的 Error Specification
章节的描述来工作。这个处理器处理来自 data fetcher 的异常。任意的 RuntimeException
将会被转成 INTERNAL
类型的 GraphQLError
。对于一些指定的异常类型,会使用一个指定 GraphQL 错误类型。
异常类型
GraphQL 错误类型
描述
AccessDeniedException
PERMISSION_DENIED
当一个 @Secured
检查异常
DgsEntityNotFoundException
NOT_FOUND
当请求的实体(基于查询参数)找不到的时候,由开发者手动抛出异常
映射自定义异常
映射应用指定异常成为带有明确意思异常,返回给客户端是非常有用的。你可以通过注册一个 DataFetcherExceptionHandler
来做到。请确认扩展或者代理到 DefaultDataFetcherExceptionHandler
类,这是框架的默认异常处理器。如果你没有扩展/代理到这个类的话,你将会失去框架内建的异常处理器。
以下是一个自定义的异常处理实现。
下面的 data fercher 抛出 MyException
。
response 查询 hello
字段的结果
指定异常
这里有两组我们在 GraphQL 中典型遇到的错误:
综合错误:指非可预见的错误,而且不能期望终端用户能够修复。这类的错误通常适用于多种类型和字段。这样的错误将会在 GraphQL Response 中的
errors
数组中出现。作为数据的错误:指能够给与终端用于以指导的错误。(例如:“标题不能使用在你的国家” 或者 “你的账户被锁定了”)。这类错误是典型指出详细用法和在特定的字段或者特定的子集中使用。这些错误是 GraphQL schema 的一部分。
GraphQLError 接口
GraphQL 的说明提供了一个错误结构的迷你指导。它只有一个必须的,没有定义格式的 String 类型的 message
字段。在 Studio Edge 中我们应该有一个清晰的,更有表现力的约定。以下是我们可以使用的定义:
字段
类型
描述
message
(non-nullable)
String!
描述一个错误的字符串,为开发者提供一个可以理解的错误
locations
[Location]
代码定位数组,每个定位将会是 Key 为 line
和 column
的 Map
, 从1开始可以描述关联元素的自然数。
path
`[String
Int]`
如果错误是关联了一个或者多个在响应中的字段时,这个字段将会在响应中描述错误字段的路径(可以让客户端找到是否有一个真的 null
结果还是因为运行时异常才为 null
)
extensions
[TypedError]
TypedError 接口
Studio Edge 定义以下 TypedError
:
字段
类型
描述
errorType
(non-nullable)
ErrorType!
枚举化的错误代码,就是一个很粗的错误描述,足够客户端进行分支逻辑。
errorDetail
ErrorDetail
一个可以提供错误细节的枚举,包括它特殊的原因(因为并不能有据可查,所以需要可供更改的一个主要内容)
origin
String
记录错误来源的名称(为了实例化 backend service,DGS,gateway,client library, 或者 client app 的名称)
debugInfo
DebugInfo
如果请求包含了一个想要 Debug 信息的标志,这个字段将会用额外的信息显示它(就像一个 stack trace 或者来自上游服务器额外的报告)
debugUri
String
一个页面的 URI,包含了有可能对 debug 错误有帮助的额外信息(应该是一个有序错误的一般页面,或者是一个有错误详细情况的特别说明页面)
错误类型枚举
以下表格显示了可用的 ErrorType
enum
值:
类型
描述
HTTP 模拟
BAD_REQUEST
表示请求错误。重复同样的请求并不能解决问题。很有可能是查询或者参数不能被反序列化造成的。
400 Bad Request
FAILED_PRECONDITION
表示因为系统操作不可用,操作执行被拒绝。比如,在删除文件夹的时候,这个文件夹并不是空的,则 rmdir
操作在一个非空的文件夹上等等。如果客户端能够在一旦得到失败,不等系统修复,立刻重试的时候,请使用 UNAVAILABLE
.
400 Bad Request, or 500 Internal Server Error
INTERNAL
表示发生了不可预见的内部异常:打破了下游系统提供的常量。这个错误为很严重的错误而保留。
500 Internal Server Error
NOT_FOUND
可能请求了不存在的资源(比如:错误的资源ID),或者一个资源以前存在,而现在不存在(比如:缓存过期)。提醒服务端开发者:如果一个用户实体类的请求被拒绝可以使用 NOT_FOUND
,就像首次展示的特性或者未公开的允许列表。如果用户本身的类被拒绝,就像基于用户的权限,应该使用 PERMISSION_DENIED
。
404 Not Found
PERMISSION_DENIED
表示没有足够的权限执行这个特定的请求。PERMISSION_DENIED
不应被用于因为资源或配额消耗殆尽的拒绝,也不应被用于权限相关的拒绝(应该使用 UNAUTHENTICATED
代替)。这个错误不应暗示一个请求是否有效或者请求的资源是否存在或者满足其他前置条件。
403 Forbidden
UNAUTHENTICATED
表示这个请求没有有效的权限,但是这个路径是需要权限的。
401 Unauthorized
UNAVAILABLE
表示当前服务并不可用。这更像是一个临时的,有可能过一会重试一下就正常了。
503 Unavailable
UNKNOWN
可能返回这个错误,比如,当从另一个地址空间收到了一个错误,对于当前的地址空间并不知道这个错误。API 引起了这个错误,但是不能返回足够的错误信息。如果客户端遇到一个不明 errorType
,将会理解为 UNKNOWN
。不明错误不应触发特殊的行为。它们应该与INTERNAL
一样被同等对待。
520 Unknown Error
HTTP 模拟仅仅是提供了一个粗糙的映射,是一个快速的概念解释,通过HTTP指定的模拟值来判断错误。
最后更新于
这有帮助吗?