2010-06-18 75 views
8

我已经探索了一下,但是当请求成功时我没有看到HTTP状态码,但是在“不返回点”之后有一个错误。例如,假设你处理一个请求,它将其提交给数据库,但在返回结果时你运行内存,或者遇到一个NPE,或者你有什么。它已经是200响应,但现在,在内部,您无法返回正确,格式良好的响应。“有错误成功”的HTTP状态码?

202 Accepted似乎不适合,因为我们已经处理了请求。

什么状态码表示“成功,但错误”?有人甚至存在吗?

+0

在这种情况下,您必须确定您尚未向客户端发送一些数据,因为您已经通过了不返回的要点:在数据的第一个字节之前,标题(包括状态码)是发送到浏览器。 – 2010-06-18 03:18:59

+0

heh - 授予:)。我想我说的是不可回报之前的不可回报点。不过,大多数情况下,服务器端代码在发送出去之前在内存中构建完整的响应,因为它们通常足够小,可以这样做。 – 2010-06-18 03:30:50

回答

3

如果服务器知道它遇到了问题,通常应该返回5xx错误。最通用的一种是500 Server Error,其RFC 2616定义如下:

500内部服务器错误

服务器遇到阻止它 完成请求的意外情况。

然后,客户有责任重新尝试请求。如果先前的请求是部分提交的,则服务器(或数据库)负责将其回滚,或者适当地处理重复的事务。

+1

我对这个答案并不满意。 “完成”的意思是什么?我们已经以客户请求的任何方式修改了资源。如果他们重新加载页面,他们会看到更改。就用户而言,它是成功的。对我来说,这听起来像是我们已经完成了_request_,但还没有完成_response_。 – 2010-06-18 03:27:48

+0

@Richard:我总是理解“履行”以包括回应(但我可能在这方面是错误的)。尽管如此,这种状态代码是非常通用的,只要服务器遇到无法用另一个更具体的5xx错误描述的问题,就应该使用它。我认为[@Jim](http://stackoverflow.com/users/45935/jim-ferrans)描述了我想说的更好,[在其他答案](http://stackoverflow.com/questions/3066972/ HTTP状态码换成功与 - 错误/ 3067090#3067090)。 – 2010-06-18 04:00:33

1

我同意@Daniel正确的答案是HTTP 500(服务器错误)。必须编写Web应用程序才能在发生错误时回滚事务,而不是将事情完成一半。

您可以在Web应用程序中利用的一件事是“幂等性”。这是一个函数(或操作)的属性,您可以随意多次重复它,并获得相同的结果。例如,如果读取失败,客户端可以简单地重试它直到成功。如果删除似乎失败,则客户端可以再次重试,并且无论被删除的资源是否已经消失,服务器都会将该请求视为有效。如果更新失败,客户端可以重试,直到它从服务器获得成功返回。 REST架构Web服务的方法大量使用幂等性,以便在出现错误时使操作更加健壮。

+0

为了澄清,事务已经被提交(例如,考虑在响应的编码期间发生OutOfMemoryError的情况)。为了实现幂等性,你需要实现修改控制,不是吗?让服务器跟踪提交的更改和客户端提供并更改ID。还有处理非临时性错误的情况(比如说有一个导致NPE而不是内存不足错误的错误) - 客户可以重试所有他们想要的,但它永远不会成功(尽管它已经成功第一次,以后的时间是多余的)。 – 2010-06-22 03:09:27

+0

@理查德:这“一切都依赖”。如果它是一个内容管理应用程序,并且您不介意两个“同步”更新偶尔会出现严格的顺序,您不必进行版本控制。但是如果你有更严格的约束,版本控制或时间戳可能是合适的。另一种方法是尽可能在交易范围内形成尽可能多的响应,因此OOME会导致交易中止。也许持久的消息队列持有事务请求和结果可能是你想要的(查看Apache的ActiveMQ)。 +1的探究问题! – 2010-06-23 06:03:57

4

HTTP没有这样的状态码,但有一个最佳实践可以让你处理这种情况 - 在POST操作后重定向用户。

这里是一个击穿 -

  1. POST请求试图修改服务器
  2. 如果服务器无法上的数据,它发送一个500错误指示失败
  3. 如果服务器成功,发送302重定向响应
  4. 然后,浏览器发送一个新的GET请求到服务器
  5. 如果失败,你会得到一个500错误,否则你会得到一个200

因此,您的'已保存数据但无法立即检索'的用例转化为初始POST的302重定向,随后为后续GET获得500重定向。

这种方法还有其他的优点 - 你摆脱了恼人的'你确定要重新提交数据吗?'信息。还可以保持后退/前进/刷新按钮可用。