这可能是一个菜鸟问题,所以请耐心等待。我试图通过序列化异常来将异常发送到客户端,但仍保留导致异常的堆栈跟踪。客户端可能没有导致异常类。我正在使用 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?它讲述了相同的场景。
最佳答案
我用来解决这个问题的一项技术是创建一个特殊的(显然是可序列化的)“passthrough”异常(类似于您的 MyException)。此异常采用原始异常的堆栈跟踪、消息、和类名。它重写 toString() 方法以打印原始类名来代替直通异常的类名。重要的是(正如您所注意到的),在创建此异常后不能抛出该异常。相反,使用不同的共享类,并将传递异常作为抛出到客户端的“原因”。请注意,直通异常的“稳健”实现应该迭代并替换原始异常的整个原因链。
基本示例(其中 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));
}
关于java - 使用自定义异常堆栈跟踪向客户端发送序列化异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25517360/