常见 HTTP 错误及其调试方法
在构建或调用基于 HTTP 的 GraphQL API 时,遇到错误是很常见的,尤其是在开发过程中。了解如何识别并解决这些问题可以为您节省时间和精力。
本指南概述了常见的 HTTP 和 GraphQL 错误、它们的含义以及如何有效地调试它们。它遵循 GraphQL over HTTP 规范(草案) 的建议,该规范标准化了 GraphQL 在 HTTP 上的工作方式,包括请求格式、状态码和媒体类型。请记住,具体实现可能有所不同,因此请将其视为通用指南而非权威参考。
400 Bad Request:语法或解析错误
含义
服务器无法解析您的请求。可能是 GraphQL 查询字符串格式错误,或者 JSON 正文无效。这是 GraphQL over HTTP 规范推荐的主要错误状态。
常见原因
- JSON 语法错误
- 发送纯字符串而没有将其包装在
{ "query": "..." }中 - 在不支持的情况下使用
Content-Type: application/graphql
如何调试
- 使用 Linter 或格式化程序验证您的 JSON 正文。
- 确保您发送的是带有
Content-Type: application/json请求头的POST请求。 - 检查您的 GraphQL 查询是否存在语法错误。使用 IDE 或 Linter 进行验证。
405 Method Not Allowed:错误的 HTTP 方法
含义
您使用了不支持的 HTTP 方法。大多数 GraphQL 服务器要求对 mutation(变更)使用 POST,并且可能允许对 query(查询)使用 GET。
常见原因
- 发送
PUT或DELETE请求而非POST或GET - 对 mutation 发送
GET请求,或向仅支持POST请求的服务器发送GET请求
如何调试
- 检查您的 HTTP 方法。Mutation 必须使用
POST。 - 确保您的服务器对 query 支持
GET。 - 参考 GraphQL over HTTP 规范 以确认方法支持情况。
500 Internal Server Error:非预期的服务器故障
含义
服务器端出现了问题。
常见原因
- 解析器(Resolver)中存在未处理的异常
- 服务器启动期间的 Schema 验证问题
- 中间件缺失或配置错误
如何调试
- 检查服务器日志或堆栈跟踪。
- 在解析器中添加错误处理。
带有 200 OK 的 GraphQL 错误
含义
HTTP 层请求成功,但 GraphQL 操作产生了错误。
常见原因
- 执行期间的运行时错误
- 违反 Schema 约束(例如返回了错误的数据类型,或在非空位置返回了
null)
较旧的服务器和客户端(不使用 Content-Type: application/graphql-response+json 的那些)在请求完全失败(没有 data)的情况下也可能使用 200 OK。常见原因包括
- 查询一个不存在的字段
- 向字段传递了不正确的参数
- 在非叶子节点字段上省略了选择集(Selection Set)
- 在请求中存在多个操作时未指定
operationName
如何调试
检查响应正文中的 errors 数组。如果响应包含 data 属性,那么您的查询文档可能是有效的,而您很可能遇到了运行时异常——可能是由于输入无效、访问被拒绝或服务器逻辑中的错误。
如果没有 data 字段,则请求可能在验证阶段失败。例如
{
"errors": [
{
"message": "Cannot query field \"foo\" on type \"Query\".",
"locations": [{ "line": 1, "column": 3 }]
}
]
}使用内省(Introspection)或 IDE 验证您的查询是否与 Schema 匹配。
特定于实现的响应状态码
某些 GraphQL 服务器实现可能会使用规范未明确推荐的其他 HTTP 状态码。这些因实现而异。
415 Unsupported Media Type:服务器无法理解请求的Content-Type。当发送 GraphQL 查询时使用了Content-Type: text/plain或其他不支持的类型时,可能会发生这种情况。422 Unprocessable Entity:一些实现对 GraphQL 验证错误使用此状态码,而不是200+ 错误数组。
规范在大多数情况下不推荐使用这些错误代码。不同的 GraphQL 服务器处理验证错误的方式不同。如有疑问,请使用规范支持的错误代码。
理解 GraphQL 响应格式
传统上,GraphQL 服务器使用 application/json 媒体类型返回响应。然而,GraphQL over HTTP 规范 建议客户端请求(且服务器响应)更具体的类型:application/graphql-response+json。
这种较新的媒体类型将负载标识为 GraphQL 响应,帮助客户端将其与其他类型的 JSON 区分开来,使得响应即使在使用非 2xx 状态码时也能被安全处理。受信任的代理、网关或其他中间件可能会使用 JSON 描述错误,但绝不会使用 application/graphql-response+json,除非它是有效的 GraphQL 响应。
知识点
- 服务器可能会以
application/graphql-response+json或application/json响应。 - 客户端可以使用
Accept标头请求此媒体类型:Accept: application/graphql-response+json, application/json;q=0.9(优先选择新媒体类型,但两者都接受) - 这种内容类型是推荐的,且支持度正在增长。
- 如果您的客户端使用内容协商,请确保您的服务器可以响应适当的类型或回退到
application/json。
联合 (Federation)
学习 GraphQL 联邦如何通过将服务组合成统一的 Schema 来实现模块化、可扩展的 API。