2014-04-04 50 views
2

我有很长的异常层次结构,其中一个会在二进制数据中添加长消息。因为它在图书馆,所以我不能在丢失的地方改变它。我如何截断它,而不会丢失另一个异常消息?如何截断java中的长时间异常消息

代码示例:

throw new RuntimeException("msg", 
    new RuntimeException(generateLongErrorMessage(), 
     new RuntimeException("short message", 
      new RuntimeException("important message")) 
    ) 
); 

所需的输出:

Exception in thread "main" java.lang.RuntimeException: msg 
    at xxx.excpetionMessageTruncator(Erofeev.java:18) 
    at xxx.main(Erofeev.java:14) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
Caused by: java.lang.RuntimeException: long message long message ...(truncated, original size: 100) 
    ... 7 more 
Caused by: java.lang.RuntimeException: short message 
    ... 7 more 
Caused by: java.lang.RuntimeException: important message 
    ... 7 more 
+0

你在哪里发现这个异常? – radai

+1

@radai,在我的血腥企业项目 –

+1

我的目标是非常像mbred下面说的 - 如果你知道它捕获的代码位置,你可以重建异常并去掉长信息,只是“剥离”外部层和留下根本原因。你唯一的选择是自定义记录器/ appender – radai

回答

1

更新:

我看到两种不同的方式来做到这一点,根据您的需要。我更喜欢解决方案2,因为它侵入性较小,并允许代码的所有部分与完整的例外一起工作。

1,只有一个例外类型,不需要记录变化:

捕获异常和异常复制整个堆栈异常设定一个较短的消息:

private static RuntimeException truncate(RuntimeException rt) { 
    Stack<Throwable> causeStack = new Stack<>(); 

    Throwable currentEx = rt; 
    while(currentEx != null) { 
      causeStack.push(currentEx); 
      currentEx = currentEx.getCause(); 
    } 

    RuntimeException newEx = null; 
    while (!causeStack.isEmpty()) { 
      Throwable t = causeStack.pop(); 
      newEx = new RuntimeException(truncateMessage(t.getMessage()), newEx); 
      newEx.setStackTrace(t.getStackTrace()); 
    } 

    return newEx; 
} 


private static String truncateMessage(String message) { 
    if (message.length() < 25) { 
     return message; 
    } 

    return message.substring(0, 25) + "..."; 
} 

虽然你可以使用它对任何类型的异常,结果总是一堆运行时异常。如果这不是你想要的,你可以用反射+泛型来创建一个新的相同类型的异常。 如果在构造函数中只有消息/原因的组合,这将是可管理的,但请记住,也有自定义的说明。

2,定义异常处理程序(如果你不能够赶上无论出于何种原因除外)

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html设置线程异常处理程序。从那里你可以将例外传递给你的记录器。然后你可以在记录器中执行截断。

+0

但Throwable没有setMessage()方法? –

+0

对不起,在我的ipad上涂鸦。将其更改为更完整的解决方案。 – nbred

+0

它看起来不错,但你失去了真正的异常类,我认为这很重要 –