当前位置:  开发笔记 > 编程语言 > 正文

是否有任何有效理由忽略捕获的异常

如何解决《是否有任何有效理由忽略捕获的异常》经验,为你挑选了11个好方法。

哇,我刚从外包开发人员那里拿回了一个C#的大项目,在进行我的代码审查时,我的分析工具揭示了它被认为是坏东西的一堆.其中一个令人沮丧的消息是:

Exceptions.DontSwallowErrorsCatchingNonspecificExceptionsRule  : 2106 defects 

开发人员向我保证他们有充分的理由使用所有空的catch块,有时候使用空catch块的尝试只是忽略无用的异常并使应用程序不会崩溃.我觉得这是一个警察和完整的BS.我实际查找的一些示例是数据库调用,其中记录被保存到数据库,在这种情况下,如果忽略异常,用户将返回一个正常的提示,认为一切正常,并继续他们的工作.实际上,他们的工作从未得到保存.我认为这绝对是最可怕的错误.在这种情况下,在使用空catch块的try中抛出该代码是完全错误的.但我的问题是,"这种情况在任何情况下都可以接受吗?" 我想不是,但我知道错了.



1> rjzii..:

虽然有一些合理的理由可以忽略例外情况; 但是,通常只有您能够安全忽略的特定例外情况.如Konrad Rudolph所述,您可能必须捕获并吞下错误作为框架的一部分; 并且如osp70所述,可能存在由您知道可以忽略的框架生成的异常.

但是,在这两种情况下,您可能都知道异常类型,如果您知道类型,那么您应该具有类似于以下内容的代码:

try {
  // Do something that might generate an exception
} catch (System.InvalidCastException ex) {
  // This exception is safe to ignore due to...
} catch (System.Exception ex) {
  // Exception handling
}

对于您的申请,听起来像某些类似的东西可能适用于某些情况; 但是你提供的数据库示例保存返回"OK",即使存在异常也不是一个好兆头.


完全......尽管我讨厌它,但在必要时,它至少应该指定预期被忽略的异常类型,以免忽略一些模糊的错误.并且应该发生最低限度的记录.
你相信第三方图书馆在抛出异常时不要过分热心.我不想因为其他人的错误判断而垃圾邮件我的日志文件.每条规则都有例外.
在像Rob一样的情况下,我会推荐更具体的东西,然后"安全忽略".注释为什么异常可以安全忽略,它不仅可以使代码更易于理解,还可以帮助您重新检查旧项目.

2> itsmatt..:

除非我打算对它们采取一些措施,否则我不会捕获异常.忽略它们并没有对它们做些什么.



3> Maxime Rouil..:

我有时使用WebControl,这不是页面显示的必需条件.如果失败,我不想阻止页面显示.非关键WebControl的示例将是显示广告的示例.

但是,我确实记录了错误.我只是不要重新抛出它.



4> Clayton..:

我的感觉是任何空的Catch Block都需要评论.

可能忽略某些错误是有效的,但您需要记录您的原因.

此外,您不希望将其设为通用的"catch(Exception e){}".

您应该只捕获那里预期的特定错误类型,并且已知安全地被忽略.



5> Cruachan..:

一般来说没有,事实上99%的情况都没有,但是

也有例外.我工作的一个项目是使用第三方库来处理TWAIN设备.它是错误的,并且在某些硬件组合下会抛出空指针错误.然而,在它没有实际设法扫描文档之前我们从未发现任何情况 - 因此捕获异常是完全合理的.

所以我认为如果你的代码是抛出异常,那么你应该经常检查它,但如果你遇到第三方代码,那么在某些情况下你可能会被迫吃掉异常并继续前进.



6> belugabob..:

另一种情况是,您可以免除捕获和忽略异常,这是您进行单元测试的时候.

public void testSomething(){
    try{
        fooThatThrowsAnException(parameterThatCausesTheException);
        fail("The method didn't throw the exception that we expected it to");
    } catch(SomeException e){
        // do nothing, as we would expect this to happen, if the code works OK.
    }
}

请注意,即使catch块什么也不做,它解释了原因.

话虽如此,最近的测试框架(Junit4和TestNG)允许您指定预期的异常 - 这导致这样的事情......

@Test(expected = SomeException.class)
public void testSomething(){
    fooThatThrowsAnException(parameterThatCausesTheException);
    fail("The method didn't throw the exception that we expected it to");
}



7> stephenbayer..:

我想从我收集到的最好的答案是,它可以在某种程度上被接受,但应该是有限的.您应该尝试使用另一种替代方案,如果您找不到其他替代方案,您应该充分了解代码如何工作,您可以期望特定的异常类型,而不仅仅是使用全局捕获所有"异常".忽略此异常的原因的文档应包含在可理解的注释中.



8> Dustin Getz..:

在关键代码中,可能不是,因为必须始终精确定义程序的状态.像你的数据库调用示例.

在非关键代码中,当然,我们也这样做(我们只是在消息框中显示捕获的异常并继续运行).也许插件或模块失败,但主程序不受影响.也许lexical_cast失败了,并且有一个文本故障呈现在屏幕上.无需停止该过程.



9> Kena..:

我认为这是可接受的一个例子是关键应用的一些非关键模块(例如,在航天飞机导航系统的声音反馈模块中),用于不应该发生的异常,并且不能更干净地处理.

在这些情况下,您不希望让该异常传播并导致整个应用程序失败(抱歉,没有更多的导航系统,我们的哔哔声模块崩溃了,我们真的无能为力).

编辑说,在任何这些情况下,你至少想要在某个地方记录事件.



10> osp70..:

我认为如果你有一个空的catch块,你需要记录它为什么是空的,以便下一个开发人员知道.例如,在server.transfer上,有时会抛出Web异常.我抓住了这个并评论我们可以忽略它,因为转移呼叫.



11> Robert Rossn..:

在某些情况下,可以捕获特定的异常并且什么都不做.这是一个简单的例子:

    public FileStream OpenFile(string path)
    {
        FileStream f = null;
        try
        {
            f = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
        }
        catch (FileNotFoundException)
        {
        }
        return f;
    }

您也可以这样编写方法:

    public FileStream OpenFile(string path)
    {
        FileStream f = null;
        FileInfo fi = new FileInfo(path);
        if (fi.Exists)
        {
            f = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);                
        }
        return f;
    }

在这种情况下,捕获异常(非常)稍微安全一些,因为文件可能会在您检查其存在与打开它之间被删除.

当然,有理由这样做.在.NET中,异常在计算上是昂贵的,所以你想要避免抛出大量异常的东西.(在Python中,异常是便宜的,使用异常来执行诸如摆脱循环之类的事情是一种常见的习惯.)

但这忽略了一个特定的例外.这段代码:

catch
{
}

是不可原谅的.

没有理由不捕获try块中的代码将要抛出的特定类型异常.天真的开发人员为了捕获异常而不管类型的第一个原因,"但我不知道可能会抛出什么类型的异常",这就是问题的答案.

如果您不知道可能抛出的异常类型,则不知道代码如何失败.如果您不知道代码如何失败,那么您没有理由认为只要继续处理就可以了.

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有