java - 使用自定义异常堆栈跟踪向客户端发送序列化异常

标签 java

这可能是一个菜鸟问题,所以请耐心等待。我试图通过序列化异常来将异常发送到客户端,但仍保留导致异常的堆栈跟踪。客户端可能没有导致异常类。我正在使用 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/

相关文章:

java - 如何设置Textarea的最大行数

java - EclipseLink DDL 生成错误

java - 如何使用 Java 12 的 Microbenchmark Suite?

java - 在哪里可以找到 Java API 类图?

java - 使用 Runtime#exec() 编译和执行 Java 代码

java服务无法初始化(调试帮助)

java - 如果不为空,则将值放入 map

java - Java 中 BigDecimal 的 BigInteger 幂

java - 如何在 Activity 开始时打开 drawerLayout?

java - Play Framework WebSocket 示例 - 只有一个真实源(没有假生成器)