2011-01-12 74 views
1

我正在用C#编写一个API。我传播的一些方法中有一些例外,因为我希望用户能够看到异常。但是,有些例外,我没有。为了让客户端知道,我是否需要从该方法的每个被调用者中传播?例如。API问题中的异常处理

一>呼叫B>调用C

,如果我从C重新抛出,做我需要从B和从做?另外,捕获方法的catch块(例如,从a调用的b)中的异常也将被捕获到catch块中。但是如果a是API的入口点并且b已经抛出了ex,那么会有什么区别呢?在catch块?

谢谢

+4

**从不**写`扔前;`。 – SLaks 2011-01-12 22:43:01

回答

2

异常处理的第一条规则:除非您知道如何处理异常,否则不要捕获异常。使代码看起来像catch (Exception ex) { throw ex; }毫无意义。

如果我从c重新抛出,我是否需要从b和a中做同样的事情?不,你不这样做。 c抛出的任何异常都会自动通过ba冒出调用堆栈并回到客户端代码中。另外,在一个方法的catch块(比如,从a调用)中捕获的异常也会被捕获到一个catch块中。

这是不正确的:如果b捕获异常,a不会看到它,除非b重新抛出它。

但是,如果a是API的入口点并且b有throw ex,那么会有什么区别?在catch块?

如果b发现异常然后重新抛出,则a和客户端都会看到该异常。

顺便说一下,throw ex;是不好的做法。对象跟踪它们被抛出的调用堆栈。 throw ex;会清除此调用堆栈,从而很难调试异常的根本原因。相反,要重新抛出您捕获的异常,请使用throw;

1

首先,你应该只捕获一个异常,如果你打算处理它。这可以包括日志记录,如有必要。

如果你抓住它,但希望重新丢弃,请使用:

throw; 

throw ex; 

你也会有这种异常被捕获每次重复。因此,您可能必须在ba之间执行此操作,例如,如果两者都抓住它。

0

对于这个问题,“我是否需要从该方法的每个被调用方法传播?” 答案是否定的,您不必在流程中的每个方法中都捕获异常,最好的做法是在每次调用外部代码时进行尝试捕获,在您的情况下,每次调用api。 在发现异常后,您可以:

  • 自己处理错误。
  • 重新抛出您创建的新自定义异常。
2

我认为这比您试图描述的要简单得多:如果引发异常,它会调用堆栈直到抓取。如果没有捕捉到,程序就会终止。如果发现异常,则由catch块决定如何继续。选项有:

  1. 以某种方式处理情况,不要再扔掉。在这种情况下,执行只会在catch块之后继续。
  2. 重新发现异常。在这种情况下,异常继续沿着调用堆栈走,直到下一个catch块被击中。
  3. 抛出另一个异常:与2相同,但抛出了不同的异常。新的异常通常将原始异常保存为内部异常。这样,您的API的客户端就会知道异常来自哪里。