REST API 错误代码 500 处理

Posted

技术标签:

【中文标题】REST API 错误代码 500 处理【英文标题】:REST API error code 500 handling 【发布时间】:2015-03-05 18:18:32 【问题描述】:

我们正在构建一个新的 REST API。

我认为永远不应该返回错误代码 500(内部服务器错误)。

现在,当然,如果您知道客户端的参数有误,或者您可以控制一切,并且可以返回一些适当的错误代码(例如 422)。

因此,如果发生意外错误,服务器可以:

    不捕获意外错误,以便向客户端发送 500 个气泡 捕获任何意外错误并返回一些指示“意外情况”的错误代码(老实说,我找不到任何此类错误代码!)

还有其他选择吗?

【问题讨论】:

【参考方案1】:

这是服务器错误,而不是客户端错误。如果不将服务器错误返回给客户端,则不会为它们创建完整的状态代码类(即 5xx)。

您无法隐瞒您犯了编程错误或您依赖的某些服务不可用的事实,这当然不是客户的错。在这些情况下返回 5xx 系列以外的任何其他范围的代码都是没有意义的。

RFC 7231 mentions in section 6.6. Server Error 5xx:

5xx(服务器错误)类状态码表示服务器 意识到它有错误或无法执行 请求的方法

情况正是如此。代码“500 Internal Server Error”没有任何“内部”意义,它不应该暴露给客户端。

【讨论】:

明白,我同意。我试图找出如果开发人员正在处理所有案例是否可以有所作为。其实这样想是没有意义的。开发人员捕获意外错误并返回 500 或未捕获它没有区别 - 测试失败,这是我猜的重要问题。 如果您想区分已处理和未处理的服务器异常,您可以使用日志记录(在服务器端)或在请求正文中(因此客户端,在本例中为您的测试)。 有帮助的澄清。但是由于请求正文中的任何格式问题,这 500 状态代码是否可以从服务器返回?【参考方案2】:

真正的问题是它为什么会产生 500 错误。如果它与任何输入参数有关,那么我认为它应该在内部处理并作为 400 系列错误返回。通常 400、404 或 406 适合反映错误输入,因为一般约定是 RESTful 资源由 URL 唯一标识,而无法生成有效响应的 URL 是错误请求 (400) 或类似的。

如果错误是由请求显式或隐式提供的输入以外的任何其他原因引起的,那么我会说 500 错误可能是合适的。因此,数据库连接失败或其他不可预知的错误可以准确地表示为 500 系列错误。

【讨论】:

"如果它与 任何输入参数 [..]: 400" - 如果错误是由未捕获的 null 取消引用引起的怎么办请求变量的异常?它是由请求(客户端)触发的编程错误(服务器)引起的。如果服务器逻辑不需要请求变量,但程序员确实假设(因此不检查)它怎么办?重点是:大多数 Web 框架在检测到服务器软件异常终止时都会返回 5xx 代码。此框架无法区分客户端错误和服务器错误。 没错,但这个问题是在测试一个可能是新的服务并征求有关最终如何处理这种情况的反馈的背景下提出的。如果我正在测试新服务并通过边缘案例输入测试用例生成 500 个,我会将其标记为失败的测试并与开发人员一起处理测试场景,或者使用更具描述性的错误(400、404 等)或正确服务的请求 (200)。 500 个错误确实有不可预见的来源,但您可以/应该尽可能多地防范它们,即使这只是提供更多信息的错误。【参考方案3】:

一般而言,5xx 响应代码表示非编程故障,例如数据库连接故障或其他一些系统/库依赖项故障。在很多情况下,期望客户端可以在未来重新提交相同的请求并期望它成功。

是的,一些 web 框架会响应 5xx 代码,但这些通常是代码缺陷的结果,并且框架太抽象而无法知道发生了什么,所以它默认为这种类型的响应;然而,这个例子并不意味着我们应该习惯于返回 5xx 代码作为与进程外系统无关的编程行为的结果。有许多定义明确的响应代码比 5xx 代码更合适。无法解析/验证给定的输入不是 5xx 响应,因为代码可以容纳更合适的响应,不会让客户认为他们可以重新提交相同的请求,而实际上他们不能。

需要明确的是,如果服务器遇到的错误是由于 CLIENT 输入引起的,那么这显然是一个 CLIENT 错误,应该使用 4xx 响应代码来处理。期望客户将更正其请求中的错误并重新提交。

但是,捕获任何进程外错误并将其解释为 5xx 响应是完全可以接受的,但请注意,您还应该在响应中包含更多信息以准确指出失败的原因;如果您可以包含 SLA 时间来解决,那就更好了。

我认为将“意外错误”解释为 5xx 错误并不是一个好习惯,因为会发生错误。

这是一个常见的警报监视器,用于开始对 5xx 类型的错误发出警报,因为这些错误通常表示系统失败,而不是代码失败。所以,相应地编码!

【讨论】:

【参考方案4】:

您建议“捕获任何意外错误并返回一些错误代码表示“意外情况””,但找不到合适的错误代码。

猜猜看:这就是 5xx 的用途。

【讨论】:

【参考方案5】:

80% 的情况下,这可能是由于 soapRequest.xml 文件中的错误输入

【讨论】:

以上是关于REST API 错误代码 500 处理的主要内容,如果未能解决你的问题,请参考以下文章

处理 Django Rest Framework 中的 500 个内部错误

Django Rest框架 - 如果表包含响应显示服务器错误(500)的数据

Paypal Rest API 内部服务器错误 500

PayPal REST API 为信用卡令牌返回 500 服务器错误

如何处理 Spring Rest API 上的内部服务器错误(500)以自定义消息?

500内部服务器错误;在spring Boot rest api中使用POST方法时