Fortify 最终抛出内部 bug

Fortify throw inside finally bugs

我遇到了强化问题: 糟糕的错误处理:最后扔进里面 我没有在 finally 块中抛出异常,但它仍然显示此错误。 请在下面找到代码。`

catch( IOException | JSONException | URISyntaxException e)
    {
        if(instream == null) {
            throw new  IOException("InputStream not valid");
        }
        return e.getMessage();
    }finally {
        if(instream != null ) {
            instream.close();
        }
        if(urlConnection != null ) {
            urlConnection.disconnect();
        }
    }

不,你是:inStream.close()能投。

通常,'curing' 警告实际上会使您的代码变得更糟。这是问题所在:

IF try 块抛出未捕获的异常

在这种情况下,finally 块被执行。假设 finally 块运行 in.close();。特别是如果我们到达这里的全部原因是 in 断开连接并开始抛出 IOEx,那么这很可能也会抛出 IOEx。从 finally 块中抛出的任何异常 'overwrite' 导致我们来到这里的异常,以及来自该关闭调用的堆栈跟踪的用处要小得多。

所以这很糟糕

我们可以通过将 finally 块中的 in.close() 包装在 try { .. } catch (Exception ignore) {} 中来修复它。但是,另一种情况真的很糟糕:

如果我们到了这里'normally'

输入流可能完美运行,然后当您关闭它时,它会抛出错误。很长一段时间以来,常识是 'eh, whatever, who cares, I got my data',但这不是一个明智的想法:如果输入的关闭最终抛出,这可能意味着您实际上还没有获得所有数据,否则,为什么要这样做?所以,现在,默默地吞下任何异常是一个坏主意,我们想抛出它。

不费吹灰之力,使用一个布尔值来跟踪我们是如何到达 finally 块的,并根据它,是否吞下那个异常,不可能做到这一点对。

因为这太棘手了,try-with-resources 实际上做对了 并生成了必要的样板文件。

因此,真正的解决方案是:如果您要在 finally 块中关闭资源,则不要这样做。请改用 try (ResourceType r = new ResourceType()) { ... } 语法。

如果你真的做不到,你也不能通过创建一个自动关闭的包装器来让它工作,例如如果资源为空则什么都不做,那么你基本上被迫告诉你的 linter 别再抱怨了。