您喜欢在哪里捕获异常,为什么?
您喜欢在哪里捕获异常,为什么?
我有兴趣了解人们发现将 try/catch 块放在哪里有用,希望可能出现一些通用模式。 我将用 C++ 发布我的两个示例答案,但任何语言都可以。
请为每个答案提供一个地点和原因。 谢谢。
Where do you like to catch exceptions and why?
I'm interested in seeing where people find it useful to put their try/catch blocks in the hope that some general patterns might emerge. I'll post my two example answers in C++ but any language is fine.
One location and reason per answer please. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
在 Delphi Windows 应用程序中,应用程序的主消息处理循环(即在调用堆栈的底部)通过显示消息框来处理异常。 在我看来,这是处理异常的最佳位置。
通过在您自己的方法中捕获异常,其唯一目的是向用户显示消息框,您就拒绝了任何调用您的方法的代码,因为您知道异常确实发生了,并且该方法实际上失败了。
我只会在以下情况下处理异常:
In a Delphi Windows Application, the main message handling loop for your application (i.e. at the bottom of the call stack) handles your exceptions by showing a message box. In my opinion this is the best place to handle exceptions.
By catching exceptions in your own methods for the sole purpose of showing a message box to the user, you're denying any code calling your method of knowing that an exception actually occured and that the method infact failed.
I would only handle an exception if:
(在开始之前:我是一个 Java 人)
我的建议是:
handle(Exception e)
方法编写一个异常处理程序类,并首先将其发布给团队,并确保每个人都使用它来处理异常。 根据不断变化的异常处理场景,稍后继续添加重载的“handle”方法,以便仅需要修改处理程序。(Before I begin: I am a Java guy)
What I recommend:
handle(Exception e)
method and release that to the team initially and ensure that everyone uses it to handle exceptions. Based on changing exception handling scenarios, keep adding overloaded 'handle' methods later on so that only the handler need to be modified.两个位置:
Two places:
不要抓住任何你没有准备好并且没有能力处理的东西。
因此,具有顶级异常处理到位,以您喜欢的方式处理意外异常,然后仅捕获您需要的内容(尽可能接近可能发生的位置)以获得所需的功能。
您应该只做以下两件事之一:实际做一些事情来解决/解决问题,或者重新抛出一个更具描述性的异常,该异常将捕获的异常作为其
innerException
。编辑:如果您需要一个
finally
块(例如,释放您在代码中分配的内容),并且您没有任何有用的方法来处理可能弹出的相同逻辑适用的任何异常:只需不要不处理他们。 相反,请使用 catch { throw; } 将异常重新抛出到更高级别,同时保持所有异常信息完整。 (或者干脆省略 catch 块,我认为/希望它能起到同样的作用?)Don't catch anything that you are not prepared to and able to handle.
So, have top-level exception handling in place to bomb the application the way you like on unexpected exceptions and then only catch the stuff you need (as close to where it might be occuring) to get the functionality that is needed.
And you should do only one of two things: actually do something to solve/work around the problem or rethrow a more descriptive exception that has the caught exception as its
innerException
.EDIT: If you need a
finally
block (e.g. to release something you allocated in your code) and you don't have anything useful to do with any exceptions that might pop up the same logic applies: simply don't handle them. Instead, use acatch { throw; }
to rethrow the exception to a higher level while keeping all exception info intact. (Or simply omit the catch block, which I think/hope does the same thing?)我尝试只捕获那些我可以处理的异常。
我讨厌这样的代码:
我特别讨厌的是,这通常会中止线程,因为三行后将有一个对 i 的访问,并假设 i != null。
然后,您将阅读堆栈跟踪并滚动、滚动、滚动日志,直到找到第一个导致其他所有内容崩溃的重大错误。
无论如何,我希望 Java 不会强迫我捕获我无法处理的异常。 但我能做的是:
我在函数定义中声明了很多“抛出”。
我仍然梦想着有一天,当 Eclipse 遇到未捕获的异常时,它会在正确的行中自动打开调试器。 那天,我的方法将打开正确的线路。
在其他语言中,例如 Smalltalk,我只捕获我可以处理的错误。 当输入不符合我的期望时,我很乐意抛出未捕获的异常。
我的想法是我不希望记录或记录错误。 我想把它修好。
I try to catch ONLY those exceptions that I can deal with.
I HATE code like this:
What I especially hate is that what this usually does is to abort the thread anyway, because three lines later there will be an access to i that will assume that i != null.
Then you will read your stacktrace and scroll and scroll and scroll the log til you find the first signifant mistake that made everything else fall apart.
I wish Java didn't force me to catch Exceptions that I cannot deal with, anyway. But what I can do is this:
And I declare a lot of "throws" in my function definitions.
I am still dreaming of the day where Eclipse will automatically open a Debugger in the correct line when it will get an uncaught exception. That day, my method will open the correct line.
In other languages, like Smalltalk, I catch only the errors that I can handle. And I happily throw uncaught exceptions when the input does not meet my expectations.
The idea is that I don't want the error to be logged or documented. I want it fixed.
我总是在 main() 中放置一个 catch 作为最后的手段:
I always put a catch in main() as a catch of last resort:
在 C# 和 Java 中,我更喜欢根本不捕获异常。 如果我无法避免它,我会立即重新抛出运行时异常。
我将始终使用具有所需最大范围的最贪婪的 catch 块,但始终具有最具体的异常类型。 由于在 99.99% 的情况下,catch 块的结果是另一个 throw,因此我尝试将完整方法保留在 try 块中。
In C# and Java I prefer to not catch exceptions at all. If I can't avoid it, I rethrow a RunTime-exception immediately.
I'll always use the greediest catch block that has the largest scope needed, but always with the most specific exception-type possible. Since the outcome of the catch block is another throw in 99.99% of the cases, I try to keep the full method within the try block.
我喜欢尝试将异常处理代码与其他代码分开,因此我通常创建一个辅助方法来执行实际逻辑,而外部方法只处理异常处理。 我一直认为这使代码看起来更干净并且更具可读性。
I like to try and keep my exception handling code separate from my other code so I usually create a helper method that does the actual logic and the outer method just deals with exception handling. I've always thought this gives the code a clean look and makes it more readable.
我喜欢捕获控制器中处理从视图触发的事件的处理程序。 如果异常提供了强有力的安全保证,那么这是一个有用的捕获点,因为它的级别足够高,可以报告错误,并且处理程序通常是原子的,并且与用户刚刚完成的操作相关,因此希望他们能够解决这是怎么回事。
I like to catch around handlers in the controller that handle events fired from the view. If exceptions give the strong guarantee of safety this is a useful catch point because it is high level enough to report the error and the handlers are usually atomic and related to something that the user has just done so hopefully they'll be able to work out what's going on.