使用 try catch 的 n 层

问题描述 投票:0回答:2

我正在开发一个 n 层应用程序,并且仅在我的表示层中进行 try/catch。如果数据层或者业务层出现错误,这个错误就会被我的表示层的try/catch捕获。这很好吗,还是我应该在每一层的每个方法中使用 try catch ?

exception
2个回答
2
投票

一般来说,最好在异常发生的地方捕获异常,以便您的代码可能执行某些操作来修复/适应/对问题做出反应。这个“做某事”是什么取决于具体情况。例如,如果您的服务层调用失败,您可能需要重试该调用,因为服务可能太忙;而如果您的存储过程被破坏,那么无论您重试多少次,它都会被破坏,直到数据库中的逻辑得到纠正。

如果您只想记录错误,那么在靠近错误发生位置捕获错误的用处不大。

我参与过的每个项目在应用程序的每一层都有

try-catch
块。

try-catch
的推论是快速失败的概念,它通常表示当系统立即失败而不是缓慢失败(阅读:运行数小时、数天、数周、数月甚至数年之后)时,调试效率会提高。

.NET Framework 中快速失败的一个很好的例子是使用

Convert.ToInt32()
与使用
(int)
的直接向上转换,如下所示:

int? settingValue = Convert.ToInt32(SomeSettingString);

if(settingValue == null)
{
    // Do something here
}
else
{
    // Do something else here
}

如果

SomeSettingString
可以转换为
int
,则将该值设置为 并执行
Do something else
逻辑。假设一年后,设置发生变化并返回
null
,因为转换失败,现在突然执行
Do something here
逻辑,找出这种情况发生是一个调试冒险,如果你能找到根本不出来。大多数此类问题似乎只发生在生产中,而不是开发中。

现在让我们看看同样的事情,但是通过快速失败,就像这样:

try
{
    int settingValue = (int)SomeSettingString;
}
catch(Exception ex)
{
    // Fail fast and throw exception
    throw new Exception("Fail fast");
}

现在,当设置字符串导致转换失败时,异常会立即发生。


注意:请注意,“吃掉”异常的空

int

块可能会破坏快速失败。应避免带有空

catch
块的
try
块,因为它们总是会导致“被吃掉”的异常情况。

不要这样做:

catch



1
投票

try { // Exception waiting to happen here } catch(Exception ex) { // Catch-all, because all exceptions derive from Exception class // So this will eat exceptions and pretend like they never happened }

如果这就是你正在做的事情,你不妨回到VB旧的
void method() { try { // some code here that may potentially throw an exception } catch ( /* anything here */) { // code right here to handle that exception } }

系统,因为你没有获得任何东西。异常为错误处理提供了两个主要优点:能够以不同的方式轻松处理不同类型的错误,以及能够在程序的调用堆栈中进一步捕获错误。这是您在这里问的第二个优势。

因此我们看到您确实希望允许异常“冒泡”到更高层,因为这是我们出现异常的一个重要原因......但是您是否总是想在表示层处理它们?不,我们可以做得更好。有时,可能存在关于如何响应数据层的某些异常的业务规则。有时,数据层本身可能能够处理异常并从异常中恢复,而无需通知其上方的层。

此外,异常的一个优点是它可以让您在较低层编写更简单的代码,从而减少错误处理代码的程序执行正常流程的中断。这是以在表示层中放置更多的 try/catch 为代价的。再次强调,这并不意味着表示层是处理它们的唯一位置,但这是努力确保它们不会未被捕获地通过表示层的地方。如果您无法在其他地方处理它们,请确实有办法在表示层中捕获它们并以友好的方式向用户显示它们。使用相同的机制来记录或报告异常也是一个好主意,这样您就可以获得有关应用程序失败位置的良好指标,然后使用该信息来改进应用程序。

当您确实处于最后一搏的异常处理程序中时,您可能还需要考虑终止应用程序。如果确实发生了意外的事情,例如未处理的异常通过表示层,那么有一个有效的思想流派表明继续运行该程序可能不是一个好主意。但即使在这种情况下,您也需要捕获并尝试报告异常,然后尽可能优雅地崩溃。

© www.soinside.com 2019 - 2024. All rights reserved.