这可能是一个菜鸟问题所以请耐心等待。我试图通过序列化将线路上的异常发送到客户端,但仍保留原因异常堆栈跟踪。客户端可能没有导致异常类。我正在使用setStackTrace
方法,但令我感到困惑的是它为什么不起作用。
public class MyException extends Exception {
private static final long serialVersionUID = 1L;
public MyException(final String message, final StackTraceElement[] stackTrace) {
super(message);
this.setStackTrace(stackTrace);
}
}
public static void main(String[] args) throws Throwable {
MyExceptione = new MyException("Failure", new Exception("Original Exception").getStackTrace());
throw e;
}
这将打印以下内容。缺少根本原因堆栈跟踪。
Exception in thread "main" pkg.MyException: Failure
at pkg.MyException.main(MyException.java:20)
知道我做错了什么吗?
类似的问题:Initialize exception with stacktrace from another exception?它讲述了同样的情况。
答案 0 :(得分:1)
我用来解决这个问题的一种方法是创建一个特殊的(显然可序列化的)" passthrough"异常(类似于您的MyException)。此异常采用原始异常的堆栈跟踪,消息,和类名。它会覆盖toString()
方法以打印原始类名来代替直通例外的类名。重要的一点(正如你所注意到的),是你在创建它之后不能抛出这个异常。相反,使用另一个共享类与直通异常作为"原因"被抛到客户端。注意一个强大的" passthrough异常的实现应该遍历并替换原始异常的整个原因链。
基本示例(客户端已知ServerException和PassthroughException):
public class PassthroughException extends RuntimeException {
private final String _originalName;
public PassthroughException(Throwable t) {
super(t.getMessage(), passthrough(t.getCause()));
_originalName = t.getClass().getName();
setStackTrace(t.getStackTrace());
}
public String toString() {
String msg = getMessage();
return _originalName + ((msg != null) ? (": " + msg) : "");
}
private static Throwable passthrough(Throwable t) {
return ((t != null) ? new PassthroughException(t) : null);
}
}
try {
// ... do some stuff on server ...
} catch(Throwable t) {
throw new ServerException(new PassthroughException(t));
}