异常处理实践顶级与每个功能

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

我见过几种异常处理方法。我见过的两种最常见的模式是:

  • 尝试捕获每个函数,记录异常并重新抛出
  • 在最顶层尝试 catch(如 main 函数),记录异常并重新抛出

如果有的话,哪一种是更好的做法?或者在什么情况下您会选择一种方法而不是另一种?

c# .net exception
5个回答
7
投票

这取决于您的应用程序,并且是一种设计选择,尽管选项 1 非常混乱。您应该只捕获准备以某种方式处理的异常,而不是任意捕获每个异常。在大多数语言中,异常都会有堆栈跟踪供您查看,因此无需在每个级别进行日志记录。当我说以某种方式处理时,可能是记录并重新抛出,或者可能是记录,通知用户一些错误,然后继续运行

顺便说一句,您不应该在代码中使用异常作为逻辑。如果您发现自己使用 try catch 块作为流量控制,那么您应该考虑重新设计。例外就是例外。


4
投票

选项 1 被认为是不好的做法,应该避免,而选项 2 是您应该遵循的最佳实践。

默认情况下,异常处理的原则是让异常自然抛出,并像选项 2 一样在顶层捕获它们。只有一种情况你应该捕获异常,那就是你想要基于异常执行一些业务逻辑。如果你不处理业务逻辑,就不要抓住。

选项 1 的更多缺点:

  1. 大量的try-catchre- throw使你的代码可读性较差,

  2. 考虑在每个方法中捕获异常并记录它们将使日志文件记录相同的异常信息,这是不必要的。


2
投票

我见过最多的做法是:

捕获那些您准备好处理的异常。例如,插入重复的主键,捕获它,并向用户显示一条适当的消息,以输入记录中唯一的内容。

对于应用程序的其余部分,库中不会有异常处理。这样,如果发生异常,它可能会弹出到上层,在那里可以进行适当的处理。

您可能会看到这篇文章:.NET 中的异常处理最佳实践


1
投票

我通常会完全避免选项 1,因为我看不到真正记录异常传递的每个函数的价值。您通常主要关心异常发生的地方。可能存在需要了解其到达那里的确切流程的情况,但您可以从异常调用堆栈中获取该信息。

我处理异常的原则是只有当我正在用它做某事时才捕获它们。如果 catch 的唯一目的是重新抛出,那么捕获它就没有意义。 但是,如果我确实捕获了它,然后记录它/用自定义的特定异常包装它/处理它,那么这就是一个足够好的理由。我通常发现此类任务并非在每个功能中完成,但最常见的是在层/层边界完成


0
投票

我没有看到底层堆栈中的日志记录和重新抛出异常有很大的区别。因此,仅仅重新抛出日志记录似乎浪费了异常处理。如果您正在做一些有意义的事情(需要清理内容、抛出新的域异常或在抛出之前进行第二次尝试),这可能会很有用。

但是记录异常本身可以在最高级别轻松完成。

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