62

我正在和一位同事讨论这个问题,我们无法达成协议,所以我想听听你的想法。对此我有自己的看法,但我不会为你剧透。

我应该什么时候返回一个SOAP 错误,什么时候应该返回一个包含错误信息的结果对象?假设这是一个可以被各种系统(.NET、Java 等)使用的通用 Web 服务。结果对象将有一个 isError 标志、一个 errorType(类似于特定的异常类型)和一条消息。

需要考虑的几点:

  1. 数据验证错误是错误吗?
  2. 是否应该有错误(对于非常特殊的情况)和结果对象(对于“预期”错误)的组合?
  3. 您将如何对 SOAP 错误进行分组(关键 [空引用] 与验证 [邮政编码不正确])?
  4. 快速失败与必须记住检查错误
  5. 最佳实践、模式、标准等。

文章链接有效。尽管听起来我想要您的意见,但请坚持事实(x 更好,因为 y 和 z...)

4

4 回答 4

60

大多数 SOAP 客户端会将错误转换为运行时异常(如果客户端语言支持的话)。考虑到这一点,我认为您可以将问题改写为“我什么时候想抛出异常而不是返回错误值”?我相信你可以找到很多关于这个 API 设计的意见,特别是那个主题。

也就是说,返回错误通常对客户端没有帮助:

  1. 客户端需要手动枚举和处理您的错误代码,而不是允许存根代码生成并抛出适当类型的异常。使用错误代码可以防止客户端使用面向对象的技术,例如通过超类处理异常。

  2. 如果您不将错误代码作为 WSDL 的一部分;客户将没有关于它们是什么或何时发生的文档。类型错误是 WSDL 的一部分,因此(在一定程度上)是自记录的。

  3. 故障消息可以包含客户端可以用于错误报告和恢复的特定于故障的上下文。例如,抛出包含实际无效输入元素和原因的输入验证错误。如果您返回带有错误代码和不透明字符串的结果,客户端别无选择,只能将您的错误消息传递给用户,这会破坏国际化、UI 一致性等。

要回答您的具体问题:

  1. 验证错误是一个错误。想象一下,如果您从具有有限错误处理能力的 AJAX 客户端调用 Web 服务;您希望服务返回 5xx HTTP 代码,而不是带有一些意外响应的 400 成功代码。

  2. 不可以。API 应该提供一致的错误报告接口。WSDL 设计是 API 设计。强制客户端实现两个不同的错误处理程序不会让客户端的生活更轻松。

  3. 故障设计应该反映您的请求/响应模型并显示适合服务抽象的信息。不要设计 NullReference 错误;设计一个 XYZServiceRuntimeFault。如果客户端经常提供无效请求,设计一个 InvalidRequestFault,带有适当的子类,以便客户端可以快速找出无效数据在哪里。

于 2010-06-21T18:17:11.020 回答
45

结果对象应该只包含结果。如果您的结果对象提供了另一个系统上发生的错误列表,那么这就是您何时可以拥有“isError”标志的示例;否则你不能因为结果要么有效要么无效。

发生错误时,您应该始终使用 SOAPFault。验证是一个错误,认为验证不如无法打开数据库严重是魔鬼自己的陷阱。这两种情况具有相同的影响 - 操作无法按要求完成。

因此,您应该将结果对象用于结果,将 SOAP 错误用于阻止有效结果对象的任何事情;包括但不限于错误、验证失败、警告、总线故障等。

在异常发生之前的日子里,没有选择,因此许多 API 变得不一致,并且大多数 API 在如何返回错误方面存在差异。它曾经(现在仍然是)可怕、令人困惑并且经常减慢开发速度,因为您必须查找每个 API 条目如何返回错误,并且通常如何解码或了解有关错误的更多信息。

  1. 当您考虑它时,使用 SOAPFaults / Exceptions 处理验证更合乎逻辑,并且一旦您考虑它通常会更容易。您确实需要设计验证故障类,以便它包含足够的信息来以不一定需要原始请求的方式识别违规元素。这样您就可以开始更通用地处理验证错误。

  2. 如果结果对象包含错误,则它们只能在结果的域内;例如,由于仓库中的某个人无法计数而导致产品缺货是在库存控制范围内。

  3. 区分严重错误和验证错误是不明智的,在我看来,这不是一个有效的比较,因为任何严重性级别的分配都是非常主观的。例如,在向消防员提供化学品信息的系统中,关键可能意味着着火的卡车在尝试加载警告图形时携带 UN 1298 和 UN 1436,而不是空参考。

    设计故障以使它们能够被简明地识别并相应地处理。确保它们传达足够的信息。当您有足够的信息时,Abritrary 分类是不必要的,因为故障将允许自己被识别。

  4. 将 SOAPFaults 转换为 Exceptions 是实现快速失败的最可靠方法。

  5. 最佳实践、参考资料等

于 2010-06-22T14:30:01.423 回答
8

我认为简短的回答是使用肥皂故障,除非您知道客户端将有能力处理作为结果返回的错误。如其他答案中所述,我还在考虑异常和错误结果之间的类比。

根据客户的需要,有一些灰色区域可以被合理地视为异常和结果错误。然后,您可以向服务提供一个参数,以更改这些错误类型的返回方式。默认是使用 SOAP 错误,但如果客户端设置参数来获取错误结果,则表明它愿意将其作为结果的一部分进行处理。对我来说,验证错误就在这个灰色区域。对于大多数客户端,它们应该被视为错误,但如果客户端想要使用数据来标记带有验证错误的 UI,那么将验证错误作为结果的一部分返回可能会更有用。 

于 2010-06-25T17:40:37.763 回答
1

我在服务设计中遵循的规则是:

  • 将业务级别响应(甚至业务异常)转换为响应对象
  • 技术/集成级别故障到肥皂故障

服务消费者可以相信所有类型的业务响应都来自响应对象并将其呈现给服务(业务)用户。只有在无法交付业务响应时才使用肥皂故障。

Soap 故障应通过监控触发支持警告/操作。

于 2017-02-14T15:25:05.183 回答