Java 如何获取重写异常的消息?

Java 如何获取重写异常的消息?,java,exception,Java,Exception,我开发了一个EJB服务,我的服务只能抛出一种类型的异常-MyServiceException。也就是说,所有发生的异常都被包装到MyServiceException中,并重新提交给客户端。但我不想向客户端显示堆栈跟踪(出于安全原因),我只想记录此堆栈跟踪并仅向客户端显示错误消息。因此,只需编写以下代码就足够了: catch (Exception e) { logger.error("Error when creating account", e); throw new MyService

我开发了一个EJB服务,我的服务只能抛出一种类型的异常-
MyServiceException
。也就是说,所有发生的异常都被包装到
MyServiceException
中,并重新提交给客户端。但我不想向客户端显示堆栈跟踪(出于安全原因),我只想记录此堆栈跟踪并仅向客户端显示错误消息。因此,只需编写以下代码就足够了:

catch (Exception e) {
  logger.error("Error when creating account", e);
  throw new MyServiceException("Error when creating account" + e.getMessage());
}
但是如果我有一堆方法:1-2-3。方法3抛出有意义的异常,消息为“钱不够”,所以我想向客户机显示此消息。但是方法2使用新消息“您的信用卡出现了一些问题”重新记录了此异常,因此在方法1中调用
e.getMessage()

只会返回
“您的信用卡有问题”
,而不会返回
“钱不够”
。。在这种情况下如何处理异常?如何获取我抛出的所有消息

如果这是您的代码,我建议您以不同的方式包装异常:

catch (Exception e) {
  logger.error("Error when creating account", e);
  throw new MyServiceException("Error when creating account" + e.getMessage(), e);
}
注意MyServiceException构造函数中的第二个参数。此构造函数应调用其超类的超级(消息,可丢弃)构造函数

如果是这样做的,那么您可以通过调用exception.getCause()方法来获取原始异常。然后使用exception.getCause().getMessage()获取其原始消息

通常,所有第三方API都会像上面所描述的那样进行异常包装,因此在从设计良好的库中引用异常的原因时应该没有问题

更新:组合异常消息并用新行字符分隔它们的代码示例。我还没有测试过它,但我很确定它能正常工作,更重要的是,它说明了如何做你想做的事情:

private static String printExceptionMessages(Throwable throwable) {
    StringBuilder result = new StringBuilder();
    Throwable t = throwable;
    while (t != null) {
        result.append(t.getMessage());
        result.append('\n');
        t = t.getCause();
    }
    return result.toString();
}

好啊但是我如何知道需要调用多少次
exception.getCause()
。如果异常被多次包装会怎样?换句话说,我希望所有错误消息都由我抛出,但不向客户端提供堆栈跟踪。契约是null cause表示抛出的第一个原始异常。请参阅Throwable.printStackTrace(PrintStream s)方法的代码。