前言
GraphQL 作为一种新兴的 API 查询语言,正在逐渐取代传统的 RESTful API。与传统的 API 不同,GraphQL API 通过定义一个严格的类型系统来描述 API 的数据结构和操作。同时它还提供了强大的错误处理机制。本篇文章主要介绍 GraphQL 错误处理机制的实现原理和最佳实践,希望能够帮助读者更好地运用 GraphQL 来构建出完美的 API。
GraphQL 错误处理的实现原理
在 GraphQL 中,错误信息是通过发送到客户端的响应中的 errors 字段来返回的。errors 是一个数组,每个元素都可包含以下四个属性:
- message: 表示错误的文本消息。
- locations: 表示错误发生的位置(行和列)。
- path: 表示导致错误的字段路径。
- extensions: 表示为错误提供的任何其他信息,这将是一个对象。
在 GraphQL 中,对于一个完整的查询,只要有任何一个子查询发生了错误,那么整个查询的结果就会被标记为错误,并返回一个不包含有效数据的响应。在这种情况下,对于那些已经成功查询的字段,返回的数据将会是 null。
GraphQL 能够同时处理多个错误,它会将它们放在同一个响应中返回,每一个错误都有着自己的 error 对象。这样,客户端就能够了解哪些字段或变量引起了错误,以及错误的具体原因和位置。
GraphQL 错误处理的最佳实践
以下是处理 GraphQL 错误的最佳实践:
1. 明确错误消息
GraphQL 错误处理的第一步是提供清晰、易懂的错误消息。 在你的应用程序中,GraphQL 错误消息应该包含足够的信息,以便开发人员能够了解错误的原因和应该如何解决它。同时也要确保误消息不会给黑客提供任何关键信息。
2. 将错误分类
对于不同类型的错误,应该采用不同的方法进行处理。对于常见的网络错误,GraphQL 中的错误处理方式并不适合处理。对这种类型的错误,应该使用传统的方式。而对于 GraphQL 请求中的语法错误、查询变量、字段名和类型错误,应该使用 GraphQL 本身的错误处理机制。
3. 使用自定义的错误处理方法
GraphQL 允许你重写默认的错误处理方法,你可以在自定义函数中处理所有的 GraphQL 错误。这个函数接收一个错误列表,然后你可以将错误列表中的每一个错误转换成自己的错误格式,或者创建自己的错误页面显示。这种方式使得开发人员可以在应用程序中自定义错误处理。
4. 使用 resolvers
在 GraphQL 中,Resolver 负责从解析的查询中生成具体的数据。在 Resolver 函数中,你可以捕捉一些错误,并将以及错误消息打印到日志中,或者返回一些自定义错误消息,而不是通过错误响应到客户端。
5. 搜集错误日志
在构建 GraphQL 服务时,应该将错误日志集中存储在一个适当的位置。无论服务器异常还是客户端异常,都应该记录日志并包含错误消息和出错的位置。这样你就可以及时发现代码中的问题并快速修复它。
6. 处理运行时错误
在 GraphQL 查询中,Resolver 函数可能会不小心引发运行时错误。这种错误仅应该作为日志记录下来,而不是返回给客户端,在生产环境中,可以通过将这些错误统一并发送至异常捕获服务来更好地处理这些错误。
错误处理示例
以下是一个简单的错误处理的示例,为了更好的演示,我们使用了 GraphQL Yoga,它是一个基于 Express 实现的 GraphQL 服务器框架,提供了很多的可配置选项,让我们更方便地构建 GraphQL 服务器。
-- -------------------- ---- ------- ----- - ------------- - - ----------------------- ----- -------- - - ---- ----- - ------ ------ ------ ------- --------------- ---- -- ----- ----- ----------- ------ - - ----- --------- - - ------ - ------ -- -- ------ ------- ------ -- -- - ----- --- ---------------- ---- ------- -- ------------- -------- ----- -------- ----- -- - ----- - -- - - - ---- -- -- --- -- - ----- --- ------------- ------ -- ------ - ------ - - - -- ----------- ----- -- -- - ----- --- ---------------- ---- ----- ------- - -- - ----- ------ - --- --------------- --------- --------- -- --------------- -- ------------------- -- ------- -- ------------------------
我们创建一个 hello
、error
、divideByZero
和 asyncError
四个查询。 hello
和 error
查询将返回一个字符串, divideByZero
查询将对输入参数进行除法运算,而 asyncError
查询在异步运行时发生错误。
在这个示例中,当我们查询 http://localhost:4000/
时,我们会得到下面这个 GraphQL Playground:
现在我们来逐一讨论这些查询的错误处理。
1. 明确错误消息
在上面的示例中,我们为 error
和 asyncError
查询放置了一些错误消息。在实际应用中,这些错误消息应该更详细、更有用,帮助开发人员及时定位问题。
2. 将错误分类
在上述示例中,我们使用 GraphQL 的错误处理机制处理语法错误、查询变量、字段名和类型错误。而对于网络错误等传统错误类型,则不应该使用 GraphQL 的错误处理机制。
3. 记录自定义的错误处理方法
在下面的代码中,我们自定义了一个错误处理方法,为所有的 GraphQL 错误提供了安全的错误消息和日志。
-- -------------------- ---- ------- ----- ----------- - ------- -- - ------------------ ------ - -------- -------------- ------ ----------- - - ----- ------ - --- --------------- --------- ---------- ----------- --
4. 使用 resolvers
在示例代码中,我们演示了如何在 Resolver 函数中使用 try/catch 捕获错误。我们通过查询两个整数相除的值,并在除数为零时抛出错误,来触发错误响应。
divideByZero: (parent, args, context, info) => { const { a, b } = args if (b === 0) { throw new Error('Cannot divide by zero') } return a / b },
5. 搜集错误日志
在实际应用中,应该将错误存储在适当的位置中以供后续分析和调试。以下代码演示了把错误日志记录在控制台中:
-- -------------------- ---- ------- ----- ----------- - ------- -- - ------------------ ------ - -------- -------------- ------ ----------- - - ----- ------ - --- --------------- --------- ---------- ----------- --
6. 处理运行时错误
在实际应用中,我们使用异常捕获服务处理运行时错误。以下是一些最佳实践:
- 在区分生产环境和开发环境时,确保将错误仅发送到生产日志/监控服务。
- 对于内存泄漏等严重的问题,当检测到错误时,在服务上方插入预警机制。
结论
在本文中,我们介绍了 GraphQL 的错误处理机制的实现原理和最佳实践,希望这些技巧能帮助您更好地构建 GraphQL API。虽然在大多数情况下,GraphQL 内置的错误处理机制已经足够用了,但我们仍然需要了解如何使用更高级的方法来解决更复杂的问题。因此,如果你想要更进一步地理解 GraphQL ,最好的办法就是不断实践和尝试。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/674a79b5a1ce0063548fee93