Java 错误:catch 块中抛出新异常,原始堆栈跟踪可能丢失

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6420501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 15:49:11  来源:igfitidea点击:

Java error: New exception is thrown in catch block, original stack trace may be lost

javaexceptionpmdrethrow

提问by user613114

try {
    // code which throws exception.
} catch (SQLException sqlex) {
    logger.error("Custom message", sqlex);
    **throw new CustomApplicationException("Custom message", sqlex);**
}

In the above example, on the bold line, I am getting PMD error as "New exception is thrown in catch block, original stack trace may be lost". I know this question has been asked many times also there are many online references available for the same. I have tried all the ways possible. But still I am not able to remove this PMD error. Please let me know whats wrong in this code slice. Thanks in advance!

在上面的示例中,在粗体行中,我收到 PMD 错误,因为“catch 块中抛出了新异常,原始堆栈跟踪可能丢失”。我知道这个问题已经被问过很多次了,也有很多在线参考资料可供参考。我已经尝试了所有可能的方法。但是我仍然无法删除此 PMD 错误。请让我知道这个代码片段有什么问题。提前致谢!

回答by Stephen C

I don't think there's anything wrong with that code.

我认为该代码没有任何问题。

But I also, don't think that PMD will / should give that error for that code. IIRC, you get that error with something like this:

但我也认为 PMD 不会/应该为该代码提供该错误。IIRC,你会得到这样的错误:

try {
    // code which throws exception.
} catch (SQLException sqlex) {
    throw new CustomApplicationException("Custom message");  // no cause!
}


It is possible that you have an old version of PMD or that someone has been "improving" the PMD rules that you are using.

您可能拥有旧版本的 PMD,或者有人一直在“改进”您正在使用的 PMD 规则。

回答by amoljdv06

Need to modify exception class as follow to preserve original stack trace

需要修改异常类如下以保留原始堆栈跟踪

try {
    // code which throws exception.
} catch (SQLException sqlex) {
    throw new CustomApplicationException("Any Message", sqlex);
}

CustomApplicationException.java

自定义应用程序异常.java

public class CustomApplicationException extends RuntimeException {

  public CustomApplicationException() {
  }

  public CustomApplicationException(String message) {
    super(message);
  }

  public CustomApplicationException(String message, Throwable cause) {
    super(message, cause);
  }

}

回答by drekka

Code checkers are great things for picking up problems. However in this case your code is fine and PMD probably being over protective. Check the documentation in PMD about the error and see if there is anything else you may need to consider. Then if your are still happy with your code you can add a //NOPMDtag to it to get PMD to ignore the line. I cannot remember if this is automatic or you have to configure PMD to look for //NOPMD.

代码检查器是发现问题的好工具。但是,在这种情况下,您的代码很好,并且 PMD 可能过度保护了。检查 PMD 中有关错误的文档,看看是否还有其他需要考虑的问题。然后,如果您仍然对您的代码感到满意,您可以向其中添加一个//NOPMD标签,以使 PMD 忽略该行。我不记得这是自动的还是您必须配置 PMD 才能查找 //NOPMD。

Note that inline exceptions to PMD checks like this is not really recommended either and certainly should not be regarded as a best practice. But with code checkers like PMD there will be the occasional flag which you want to ignore for some reason.

请注意,也不真正推荐像这样的 PMD 检查的内联异常,当然也不应将其视为最佳实践。但是对于像 PMD 这样的代码检查器,由于某种原因,偶尔会出现您想要忽略的标志。

回答by Eddie

What version of PMD are you using? You may be seeing a false positivethat is fixed in a newer version. (The link is just to one place where such a false positive is fixed. There may be more than one.)

您使用的是什么版本的 PMD?您可能会看到在较新版本中修复的误报。(该链接仅指向修复了此类误报的一个地方。可能不止一个。)

Depending on what version of Java you are using and exactly how you throw another Exception in a catch block, it is indeed possible to lose the full stack trace information. If you are using the latest PMD version and you get this complaint, you may want to report an error with PMD on the sourceforge page and then temporarily disable that specific instance of that complaint as others have said.

根据您使用的 Java 版本以及在 catch 块中抛出另一个异常的确切方式,确实有可能丢失完整的堆栈跟踪信息。如果您使用的是最新的 PMD 版本并收到此投诉,您可能希望在 sourceforge 页面上报告 PMD 错误,然后像其他人所说的那样暂时禁用该投诉的特定实例。

回答by Zeus

I have the same issue, we ignore the PMD issue in the pmd config file like below.

我有同样的问题,我们忽略了 pmd 配置文件中的 PMD 问题,如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<description>Custom Rulesets for production code</description>
<exclude-pattern>.*/src/test/java/.*</exclude-pattern>
<ruleset xmlns="http://pmd.sourceforge.net/ruleset/5.5.3">    
<rule ref="category/java/bestpractices.xml/PreserveStackTrace">
        <exclude name="PreserveStackTrace"/>
    </rule>
</ruleset>

we use maven, so used this config file in the maven plugin.

我们使用 maven,所以在 maven 插件中使用了这个配置文件。

Ref : https://pmd.github.io/pmd-6.0.1/pmd_rules_java_bestpractices.html#preservestacktrace

参考:https: //pmd.github.io/pmd-6.0.1/pmd_rules_java_bestpractices.html#preservestacktrace

回答by juldeh

It is necessary to throw the exception that has been triggered:

需要抛出已经触发的异常:

try {
        // code which throws exception.
    } catch (SQLException sqlex) {
        /* You can show a specific log here (See below) */
        throw sqlex;
    }

If you want to show an specific log, you can use a logger:

如果要显示特定日志,可以使用记录器:

/* Use this imports */
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
/* Declare as global variable */
private Logger logger = LoggerFactory.getLogger(this.getClass());
public Logger getLogger() {
    return logger;
}
public void setLogger(Logger logger) {
    this.logger = logger;
}
/* Use in any place */
logger.error(" an error ");
logger.trace(" operational trace ");
logger.debug(" specific trace for debugging ");

If you are using Maven, declare in your pom.xml:

如果您使用 Maven,请在您的 pom.xml 中声明:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-simple</artifactId>
                <version>1.5.2</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>