2

我正在尝试使用 C# 的 Thrift 服务。使用 REST 服务,未捕获的异常将由 Web 框架转换为 HTTP 500 响应代码。

据我所知,使用 thrift,我需要在我的 thrift 文件中声明所有可能的异常类型。这给我留下了两个我能想到的选择:

  1. 声明一个 InternalServerError 类型并将其添加到每个方法中。每个处理程序方法都需要捕获未处理的异常并重新抛出我的特殊类型。
  2. 让客户端体验这种情况下的默认行为,这似乎是套接字意外关闭。

第一个选项会起作用,但对于看起来很常见的情况来说,这似乎是相当多的变通办法。我注意到在内部使用了一个 TApplicationException ,它看起来效果很好,但我似乎无法在我的 thrift 文件中使用它,所以它不起作用。

thrift 用户在服务器端处理未捕获异常的惯用方式是什么?

4

1 回答 1

2

HTTP 500

使用 REST 服务,Web 框架会将未捕获的异常转换为 HTTP 500 响应代码。

这是“让服务器调用在未捕获的异常上惨遭失败”的委婉说法。REST 框架遵循这些策略,因为 REST 是围绕 HTTP 动词、响应和行为特意设计的。所以反过来说:HTTP 状态码不会以某种方式添加到 REST 实现中,它们是 REST 的基本原则。

惯用的异常处理

thrift 用户在服务器端处理未捕获异常的惯用方式是什么?

简短的回答:你不希望那样。

幸运的是,未捕获的异常被转换为通用的 TApplication 异常,但正如您已经观察到的,它们也可能捕获诸如意外关闭的传输之类的影响。显然,缺点是,您丢失了您可能想要传输到客户端的所有信息、上下文和异常详细信息。因此,最好有至少一种异常并将其添加到每个服务调用中,oneway方法除外。

为什么不在oneway方法上?

好吧,严格来说,你也可以添加它,Thrift 编译器会忽略它(新版本会发出警告)。事实上,由于oneway方法永远不会返回任何值,甚至不会返回异常,因此该throws子句对于oneway.

异常处理程序不是太多开销吗?

另一种选择是忍受上面解释的不受欢迎的行为。但这不是 Thrift 的设计方式,从长远来看,这将产生更多的痛苦而不是收获。

对于似乎很常见的情况,这似乎是一个相当大的问题。

并不真地。关于编码,您需要做最少的额外工作,这是真的。但你也应该看看你的努力得到了什么。

一般来说,在任何 API 外观(不限于 Thrift)上都有一个异常处理程序无论如何都是一件好事。这些异常处理程序充当最后的堡垒,并且通常用于其他目的,例如日志记录、清理与安全相关的内部等等。关于性能:异常是昂贵的,当它们被提出时。异常处理程序的纯粹存在确实只有非常有限的性能影响。

我可以重用 TApplicationException,还是从它派生?

我注意到在内部使用了一个 TApplicationException ,它看起来效果很好,但我似乎无法在我的 thrift 文件中使用它,所以它不起作用。

TApplicationException仅供内部使用,对于TTransportException和也是如此TProtocolException。你也不应该从他们那里得到。只需在 IDL 文件中声明您的异常,然后让 Thrift 编译器处理其余部分。

于 2014-01-13T21:23:03.810 回答