【问题标题】:how to truncate long exception message in java如何在java中截断长异常消息
【发布时间】:2014-04-04 14:55:57
【问题描述】:

我有很长的异常层次结构,其中之一添加带有二进制数据的长消息。我不能在扔的地方改变它,因为它在图书馆里。如何在不丢失其他异常消息的情况下截断它?

代码示例:

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

【问题讨论】:

  • 你在哪里发现了这个异常?
  • @radai,在我该死的企业项目中
  • 我的目标非常类似于下面 mbred 所说的 - 如果您知道它捕获的代码位置,您可以重建异常并删除长消息,只需“剥离”外层和只留下根本原因。您唯一的其他选择是自定义记录器/附加器

标签: java exception logging


【解决方案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 以设置线程异常处理程序。从那里您可以将异常传递给您的记录器。然后您可以在记录器中执行截断。

【讨论】:

  • 但是 Throwable 没有 setMessage() 方法?
  • 抱歉,在我的 ipad 上乱写了。将其更改为更完整的解决方案。
  • 看起来不错,但你失去了真正的异常类,我认为这很重要
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
相关资源
最近更新 更多