传递异常的正确方法是什么?(C#)

ave*_*sse 20 c# exception

我想知道将异常从一种方法传递给另一种方法的正确方法是什么.

我正在开发一个分为Presentation(web),Business和Logic层的项目,并且需要在链中传递错误(例如SqlExceptions)以在出现问题时通知Web层.

我见过3种基本方法:

try  
{  
    //error code
} 
catch (Exception ex)
{
    throw ex;
}
Run Code Online (Sandbox Code Playgroud)

(只是重新抛出)

try  
{  
    //error code
} 
catch (Exception ex)
{
    throw new MyCustomException();
}
Run Code Online (Sandbox Code Playgroud)

(抛出自定义异常,以便不传递对数据提供程序的依赖关系)
然后简单地说

//error code
Run Code Online (Sandbox Code Playgroud)

(根本不做任何事情,让错误自己冒出来)

当然,catch块中也会发生一些日志记录.

我更喜欢3号,而我的同事使用方法1,但我们都不能真正激励为什么.

使用每种方法有哪些优点/缺点?有一种我不知道的更好的方法吗?有没有被接受的最佳方式?

Pat*_*ins 17

如果你什么也不做,你应该让它在一个人可以处理它的地方.

你总是可以处理它的一部分(比如记录)并重新抛出它.你可以通过简单发送throw;而不必明确ex名称来重新抛出.

try
{

}
catch (Exception e)
{
    throw;
}
Run Code Online (Sandbox Code Playgroud)

处理它的好处是你可以确保有一些机制可以通知你,你有一个错误,你不怀疑有一个.

但是,在某些情况下,假设第三方,你想让用户处理它,在这种情况下,你应该让它继续冒泡.

  • @Earwicker,你的观点很好,但是无论如何,终结块都会运行.在糟糕的情况下,已经必须编写finally块以保持稳健.我在这里更关心的是安全隐患,而不是鲁棒性含义.坚固已经不在窗外了; 服务器崩溃了.让我们不帮助任何导致服务器崩溃的人. (2认同)

Jar*_*Par 9

我认为你应该从一个稍微不同的问题开始

我如何期望其他组件与从我的模块抛出的异常进行交互?

如果消费者完全有能力处理较低/数据层引发的异常,则完全不做任何事情.上层能够处理异常,你应该只做最小的维持状态然后重新抛出的数量.

如果消费者无法处理低级异常,而是需要更高级别的异常,那么创建一个他们可以处理的新异常类.但请确保将原始异常传递给内部异常.

throw new MyCustomException(msg, ex);
Run Code Online (Sandbox Code Playgroud)


Tay*_*ese 7

在C#中重新抛出异常的正确方法如下:

try
{
    ....
}
catch (Exception e)
{
    throw;
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此主题.


Nic*_*sen 6

仅在您期望和可以处理的异常周围使用try/catch块.如果你抓住了一些你无法处理的东西,它就会破坏try/catch的目的,即处理预期的错误.

抓住大异常很少是一个好主意.第一次捕获OutOfMemoryException是否真的能够优雅地处理它?大多数API记录了每个方法可以抛出的异常,并且这些异常应该是唯一可以处理的异常,只有当您可以优雅地处理它时.

如果你想在链条上进一步处理错误,那么就让它自己冒出来,而不是抓住并重新抛出它.唯一的例外是日志记录,但每一步的日志记录都会做大量的工作.最好只记录您的公共方法可能出现的异常情况,并让API的使用者决定如何处理它.