0

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

4

2 回答 2

1

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

如果您只想记录错误,那么在接近发生错误的地方捕获错误就没有多大用处了。

我曾经参与过的每个项目try-catch在应用程序的每一层都有块。

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

在 .NET Framework 中快速失败的一个很好的例子是使用Convert.ToInt32()与直接向上转换 using (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逻辑执行,如果你能找出这种情况,找出这种情况发生是一次调试冒险。像这样的大多数问题似乎只发生在 PRODUCTION 中而不是 DEV 中。

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

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

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

注意:请注意,快速失败可能会被catch“吃掉”异常的空块破坏。应避免try使用带有空块的块,因为它们总是会导致“吃掉”异常情况。catch

不要这样做:

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
}
于 2013-10-29T03:17:33.343 回答
0

这是您在任何级别都想避免的:一堆看起来像这样的方法:

void method()
{
   try 
   {
      // some code here that may potentially throw an exception
   }
   catch ( /* anything here */)
   {
      // code right here to handle that exception
   }
}

如果这就是你正在做的,你还不如回到 VB 的旧On Error Goto系统,因为你什么也没得到。异常为错误处理提供了两大优势:以不同方式轻松处理不同类型错误的能力,以及在程序的调用堆栈中进一步捕获错误的能力。这是您在这里询问的第二个优势。

所以我们看到您确实希望允许异常“冒泡”到更高层,因为这是我们有异常的重要原因......但是您总是想在表示层处理它们吗?不,我们可以做得更好。有时,可能有关于如何响应数据层的某些异常的业务规则。有时,数据层本身可能能够处理异常并从异常中恢复,而不会警告它上面的层。

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

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

于 2013-10-29T03:25:04.987 回答