【问题标题】:should I always know the type of my exception before I catch it? [closed]在我捕捉到异常之前,我应该总是知道它的类型吗? [关闭]
【发布时间】:2014-08-10 06:06:59
【问题描述】:

例如,写作是否被认为是不好的做法:

try
{
  #some code
}
catch (Exception e){
  #some code
}

而不是

try
{
  #some code
}
catch (ExceptionName e){  #like ArrayIndexOutOfBoundsException
  #some code
}

我想这个问题几乎适用于所有语言,无论是 Python、C++、Java...有什么想法吗?

我问是因为在我看来你不应该这样做,因为这意味着你不知道你正在处理什么样的错误以及如何处理它,但我看到有些人这样做。

【问题讨论】:

  • 这在 Python 中肯定是不好的做法...
  • 取决于上下文。
  • 这是不好的做法。您总是想要最具体的异常类型。
  • 两者都有用,但后者应该比后者更频繁地使用。
  • 这个问题虽然很有趣,但不适合 SO,因为它过于宽泛和主观。 programmers.stackexchange.com 会是一个更好的地方问这个。

标签: java python c++ exception exception-handling


【解决方案1】:

是的!

有一个例外:

你想抓住,做某事,然后重新投掷。也许您有一些资源需要在异常发生之前关闭,或者您想通知用户发生了错误:

FileResource fileResource = new FileResource("/some/path");
try {
    fileResource.open();
    fileResource.dostuff();
    //other logic
} catch (Exception e){
    fileResource.close();
    throw e;
}

因此,当抛出异常时,您可以在程序退出之前关闭资源。

始终捕获最具体的异常类型。

另外,捕获所有异常在 Python 中非常糟糕,因为您可以捕获语法异常等。

【讨论】:

  • 如果你能详细说明你的例子,那就太好了。
  • 感谢您的编辑。晶莹剔透。
  • 您不应该使用finally 块吗?这不会丢失有关异常具体来自何处的信息吗?
  • @user3580294:这更像是一个与语言无关的问题。对于 Java,是的,finally 可能是更好的选择。此外,在 Java 中,您不会以这种方式丢失任何信息(堆栈跟踪是在您创建新异常时生成的,而不是在您重新抛出它时)
  • 啊,对,错过了其他语言标签。我的错。也没有意识到在创建异常时会生成堆栈跟踪。谢谢!
【解决方案2】:

并非总是如此,如果您的代码在生产中失败,您将需要一个优雅的退出。因此,有一个很好的案例可以进行更广泛的错误处理。

def main():
    try:
        primary_process()
    except Exception as e: # Base error class that excludes keyboard interrupts
        logging.Error(e)   # and other things you don't want to catch.

但大多数时候,在您的代码中,您只处理您所期望的特定错误:

def something()
    part1() # don't expect the potential error to affect this, 
    part2() # so leave out of try block
    try:        # this infrequently raises an error for some reason, for now, 
        part3() # can't avoid. But we can handle if it happens.
    except LookupError as e: # specific error expected very infrequently
        handle(e)
    part4() 

另一个相关问答:Why is "except: pass" a bad programming practice?

【讨论】:

  • 是的,我刚看到那个,这也是一个很好的答案,非常感谢链接,还有你的回答,非常清楚,我真的觉得我今天学到了一些东西。
【解决方案3】:

是的。确切地知道您正在捕获哪种类型的异常始终是一个好习惯,因为它有助于更​​好地处理

【讨论】:

  • 如果您应该始终确切地知道您正在捕获什么类型的异常,那么除了捕获异常之外,您不应该只是处理这是一种更优雅的方式吗? (参见 Aaron Hall 的回答)。
  • 您不能总是知道所有异常,例如运行时异常。但是你应该处理你认为你的尝试可以抛出的所有其他异常,以便你可以更好地了解哪里出了问题。此外,您仍然可以在错过所有特定异常后捕获 Exception 类型的异常,以便您可以优雅地结束。例如:try{ //some code} catch(SomeException1 s1){ // } catch(SomeException2 s2){ // } catch(Exception s3) { ///优雅地结束 }
猜你喜欢
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 2013-01-25
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
相关资源
最近更新 更多