我无法理解为什么Java一旦创建便不允许更改Exception类型的异常(或其超类Throwable)的异常消息。它允许使用setStackTrace而不是消息来更改stackTrace。
我觉得用例是真实的,希望能有一些选择。
用例
我有一个控制器服务X,可以调用其他10个依赖服务。为了使调试容易,如果从属服务引发某些异常,我们希望从服务X到其上游浮现一些标识符,以轻松识别失败的请求。为此,我们具有为每个依赖关系创建和设置的requestId。
现在,为了避免所有相关服务之间的重复并简化代码,我们可以创建一个通用的拦截器,使我们能够在每次调用之前和之后进行一些工作。像-
// do some work
requestId = getRequestId(); // create or somehow get requestId
dependentService.setRequestId(requestId);
try {
dependentService.call();
}
catch (Exception e) {
e.setMessage(e.getMessage() + ... + requestId);
throw e;
}
//do some work
但是Java不允许我们设置消息。同时,我们要保留异常及其类型(可以是依赖服务定义的任何自定义类型),所以我不想做类似throw new Exception(e.getMessage() + ...)
答案 0 :(得分:3)
这不是真正的意思,但是您可以在addSuppressed
处附加另一个例外:
} catch (Exception e) {
e.addSuppressed(new ExtraInfoException(...));
throw e;
}
其中...
包含要包含的额外信息。
与添加到异常消息中相比,这样做的优势在于您可以定义ExtraInfoException
,以便它在字段中具有所需的信息,而不必从异常消息中解析出来。
话虽如此,一种附加更多异常信息的惯用方式是:
} catch (Exception e) {
throw new ExtraInfoException(e, ...);
}
具有与您返回结构化信息完全相同的优势,另外的优势是您可以直接捕获ExtraInfoException
,而不是捕获Exception
,然后反省地寻找额外的信息。< / p>
答案 1 :(得分:3)
为什么Java在Exception / Throwable类中没有setMessage?
您的问题的答案是,他们(库设计者)并不认为更改异常消息是一件有用的事情。
在很大程度上 1 ,设计人员认为他们不应该设计API直接支持所有可能的用例...包括几乎没人会遇到的晦涩的用例。 。就像你的 2 。
在您的情况下,还有其他方法可以实现您想做的事情;查看其他答案。
我快速搜索了Java错误数据库,以查看是否有人将RFE放入请求setMessage
或Throwable
的{{1}}方法中。我什么都找不到。如果您的要求稍微常见一点,那么可能会有一个RFE,其中包含拒绝原因的解释。
1-显然,有一些例外,但这不重要。
2-显然,您不同意用例是晦涩的,但这不是重点。问题是为什么他们没有实现这一点,而不是他们是否做错了。 (询问/争论他们是否错是不合时宜的,因为这是见仁见智的。)
答案 2 :(得分:1)
重置消息是某种重写历史记录的方式。捕获异常并处理它们时,您有一个catch
块。如果您需要在处理期间引发异常,则这是一个不同的问题,并且异常应该有所不同。
} catch (SomeException e) {
// here we have SomeException and we want to handle it.
// if we can't we throw a new one, because we have a problem with handling.
// if the handling problem cause is SomeException we put it at the cause.
throw new AnotherException("with some message", e);
}
在堆栈跟踪中,我们将看到由于AnotherException
而有了SomeException
,这为我们提供了有关问题根源的信息。
答案 3 :(得分:0)
只需像这样抛出新实例:
try {
...
} catch(Exception ex) {
throw new Exception ("new message", ex);
}