猿问

Java:错误处理能力差,最后扔进去

我有以下代码正在通过 fortify 运行。为什么它被标记为糟糕的错误处理,最后扔进去?


private String getResourceContent(String fileName) throws IOException {


    try (InputStream resource = ErrorResource.classLoader.getResourceAsStream(fileName)) {

        return new String(resource.readAllBytes(), StandardCharsets.UTF_8);

    } catch (NullPointerException n) {

        throw new ErrorDescriptorException(

                String.format("Error loading Error description data from Resource file [%s].", fileName), n);

    }

}


慕妹3146593
浏览 157回答 3
3回答

HUX布斯

解释让我快速引用重要部分:throw在块内使用语句finally会破坏 try-catch-finally 的逻辑进程。在 Java 中,finally 块始终在相应的 try-catch 块之后执行,并且通常用于释放分配的资源,例如文件句柄或数据库游标。在 finally 块中抛出异常可以绕过关键的清理代码,因为正常的程序执行将被中断。因此,您可以通过这样做轻松绕过清理代码,从而导致资源泄漏。虽然在代码中不直接可见,但实际上有一个隐藏 finally块,因为您使用的是try-with-resources,它会自动关闭 finally 块中的资源。例子这是官方文档中的示例:public void processTransaction(Connection conn) throws FileNotFoundException {    FileInputStream fis = null;    Statement stmt = null;    try {        stmt = conn.createStatement();        fis = new FileInputStream("badFile.txt");        ...    } catch (FileNotFoundException fe) {        log("File not found.");    } catch (SQLException se) {        // handle error    } finally {        if (fis == null) {            // This bypasses cleanup code            throw new FileNotFoundException();        }        if (stmt != null) {            try {                // Not executed if the exception is thrown                stmt.close();            }            catch (SQLException e) {                log(e);            }        }    }}抛出时绕过stmt.close()对的调用。FileNotFoundException笔记为什么要检查是否null使用 aNullPointerException而不是基本的if-else?很少有正当理由去抓捕NullPointerException。做就是了:try (InputStream resource = ErrorResource.classLoader.getResourceAsStream(fileName)) {    if (resource == null) {        // TODO Throw your exception here    }    return new String(resource.readAllBytes(), StandardCharsets.UTF_8);}通过告知无法找到资源的确切原因,它也可能有助于改进错误消息。

守着一只汪

考虑以下代码,它大致基于您的代码:String throwing(InputStream inputStream) throws IOException {    try (InputStream resource = inputStream) {        return "good";    } catch (NullPointerException n) {        return "bad";    }}你看,这里没有抛出异常。尽管如此,你还是无法移除这个throws IOException部分——那是怎么回事?好吧,InputStream#close()可以抛出它,它将位于finallytry-with-resources 语句创建的隐式块中。我想您对此无能为力,它看起来像是 Fortify 误报。

MMMHUHU

除了工具中的误导性消息之外,您的代码中实际上存在糟糕的错误处理,原因有多种:捕捉 NPE 是非常糟糕的做法。要么它是一个错误(某些东西是 null 并且不应该),要么你的代码缺少检查if (whatever == null)和相应的代码来处理这种预期情况假设这个 NPE 具有您在新 Exception 中表达的确切含义,只是猜测换句话说:在没有更多信息的情况下,不清楚您的工具到底抱怨什么。但是:不需要工具来理解:这是糟糕的错误处理。除此之外,此类工具通常会提供有关其警告的某种信息。意思是:该警告可能带有一个“错误 ID”,您应该能够在您的工具文档中查找该“错误 ID”以获得进一步的解释。
随时随地看视频慕课网APP

相关分类

Java
我要回答