你喜欢在哪里捕捉异常以及为什么?
我很有兴趣看到人们发现放置他们的try / catch块有用的地方,希望可能出现一些一般的模式。我将用C ++发布我的两个示例答案,但任何语言都可以。
请回答一个地点和原因。感谢。
答案 0 :(得分:10)
不要抓住任何你不准备和能够处理的东西。
所以,have top-level exception handling in place以意想不到的异常方式轰炸应用程序然后只捕获你需要的东西(尽可能接近它可能发生的地方)以获得所需的功能。
你应该只做以下两件事之一:实际做一些事情来解决/解决问题,或者重新抛出一个更具描述性的异常,它将被捕获的异常作为innerException
。
编辑:如果你需要finally
块(例如释放你在代码中分配的内容)并且你没有任何有用的任何有用的异常可能会弹出相同的逻辑适用:只需要处理它们。相反,使用catch { throw; }
将异常重新抛出到更高级别,同时保持所有异常信息不变。 (或者只是省略catch块,我认为/希望做同样的事情?)
答案 1 :(得分:5)
我试图抓住那些我可以处理的异常。
我讨厌这样的代码:
String s="12";
Integer i;
try {
i = Integer.parseInt(s);
} catch(ParseException pe) {
System.out.println("hihihihihihihi!!!);
}
我特别讨厌的是,这通常做的是无论如何都要中止线程,因为之后三行会有一个对i的访问,它将假设i!= null。
然后你将阅读你的堆栈跟踪并滚动并滚动并滚动日志,直到你发现第一个重大错误导致其他一切崩溃。
我希望Java不会强迫我抓住我无法处理的例外情况。但我能做的就是:
catch(Exception e) {
throw new RuntimeException(e);
}
我在函数定义中声明了很多“抛出”。
我仍然在梦想有一天Eclipse将在正确的行中自动打开调试器,因为它将获得未捕获的异常。那天,我的方法将打开正确的行。
在Smalltalk等其他语言中,我只捕捉到我能处理的错误。当输入不符合我的期望时,我很高兴地抛出未被捕获的异常。
我的想法是我不希望记录或记录错误。我希望它得到修复。
答案 2 :(得分:3)
我总是在main()中放一个catch作为最后的手段:
int main( int argc, char** argv ) {
try {
Application application( argc, argv );
return application.result();
}
catch ( const std::exception& exception ) {
fprintf( stderr, "%s.\n", exception.what() );
}
}
答案 3 :(得分:2)
在C#和Java中,我更喜欢不捕获异常。如果我无法避免,我会立即重新抛出RunTime异常。
我将始终使用具有最大范围所需的最贪婪的catch块,但始终使用最具体的异常类型。由于catch块的结果是99.99%的案例中的另一个抛出,我尝试将整个方法保留在try块中。
答案 4 :(得分:1)
我喜欢尝试将我的异常处理代码与其他代码分开,因此我通常创建一个辅助方法来执行实际逻辑,而外部方法只处理异常处理。我一直认为这样可以使代码看起来整洁,并使其更具可读性。
public void stuff() throws MyException
{
try
{
tryStuff();
}
catch (SomeLibraryException e)
{
logger.log("Some message happened", e);
throw new MyException(e);
}
}
public void tryStuff() throws SomeLibraryException
{
// Do things in here that could throw exceptions
}
答案 5 :(得分:0)
我喜欢在控制器中捕获处理从视图触发的事件的处理程序。如果异常提供了强有力的安全保证,那么这是一个有用的抓点,因为它的高级别足以报告错误,处理程序通常是原子的,并且与用户刚刚完成的事情有关,所以希望他们能够解决发生了什么事。
void Controller::on_edit_entity( const Entity& entity ) {
try {
Command::ptr command = new EditEntityCommand( entity );
push_command( command );
}
catch ( const std::exception& exception ) {
fprintf( stderr, "%s.\n", exception.what() );
}
}
答案 6 :(得分:0)
在Delphi Windows应用程序中,应用程序的主消息处理循环(即调用堆栈的底部)通过显示消息框来处理异常。在我看来,这是处理异常的最佳场所。
通过在您自己的方法中捕获异常只是为了向用户显示一个消息框,您拒绝任何调用您的方法的代码知道实际发生异常并且方法实际上失败了。
我只会在以下情况下处理异常:
答案 7 :(得分:0)
(在我开始之前:我是一个Java人) 我的建议:
handle(Exception e)
方法编写异常处理程序类,并将其最初发布给团队,并确保每个人都使用它来处理异常。基于更改异常处理方案,稍后继续添加重载的“句柄”方法,以便只需要修改处理程序。 答案 8 :(得分:-1)
两个地方: