获取完整的字符串堆栈跟踪,包括内部异常

Posted

技术标签:

【中文标题】获取完整的字符串堆栈跟踪,包括内部异常【英文标题】:Getting full string stack trace including inner exception 【发布时间】:2010-11-20 12:59:44 【问题描述】:

Java 的 e.printStackTrace() 不会打印内部异常堆栈跟踪的所有详细信息。

有没有现成的方法来生成字符串形式的完整堆栈跟踪? (除了自己格式化)

编辑

我刚刚发现了 printStackTrace() 的作用——显然它过滤掉的堆栈帧正是内部异常和外部异常所共有的那些。所以实际上它是我想要的,而不是“完整”堆栈跟踪。

【问题讨论】:

你是什么意思 - 内部异常的堆栈跟踪?捕获的异常是否在另一个异常中传播? 捕获产生的东西 ... throw new Exception("foo", e) 我刚刚发现了 printStackTrace() 的作用——显然它过滤掉的堆栈帧正是内部异常和外部异常所共有的那些。所以事实上它是我想要的,而不是“完整”的堆栈跟踪。 【参考方案1】:

我建议您使用 Apache Commons lang 中的 ExceptionUtils 类,它为此提供了有用的方法。

【讨论】:

实际上,getFullStacktrace() 仍然不打印内部堆栈跟踪。 可惜没有 printFullStacktrace() 方法,但是可以做 System.err.println(getFullStacktrace());【参考方案2】:

我最终推出了自己的(我实现了 Throwable.printStackTrace() 并对其进行了一些调整):

public static String joinStackTrace(Throwable e) 
    StringWriter writer = null;
    try 
        writer = new StringWriter();
        joinStackTrace(e, writer);
        return writer.toString();
    
    finally 
        if (writer != null)
            try 
                writer.close();
             catch (IOException e1) 
                // ignore
            
    


public static void joinStackTrace(Throwable e, StringWriter writer) 
    PrintWriter printer = null;
    try 
        printer = new PrintWriter(writer);

        while (e != null) 

            printer.println(e);
            StackTraceElement[] trace = e.getStackTrace();
            for (int i = 0; i < trace.length; i++)
                printer.println("\tat " + trace[i]);

            e = e.getCause();
            if (e != null)
                printer.println("Caused by:\r\n");
        
    
    finally 
        if (printer != null)
            printer.close();
    

【讨论】:

您是否错过了在这里打印内部异常的堆栈跟踪? if (e != null) printer.println("Caused by:\r\n"); 类似printer.println("Caused by:\r\n"+joinStackTrace(e))?【参考方案3】:

是的,您可以使用 Throwable.getStackTrace() 返回的 StackTraceElement 类并查找详细信息。

来自 API:

数组的最后一个元素(假设数组的长度是 non-zero) 表示栈底,是第一种方法 按顺序调用。

【讨论】:

以上是关于获取完整的字符串堆栈跟踪,包括内部异常的主要内容,如果未能解决你的问题,请参考以下文章

使用 sbt 和 testng 时,如何获取测试中抛出的异常的完整堆栈跟踪?

堆栈跟踪作为字符串

获取 PL/SQL 中重新抛出异常的完整堆栈跟踪(从点异常开始)

如何获取 PHP 的 getTraceAsString() 的完整字符串?

如何在 Cloudera 中查看完整的异常/错误堆栈跟踪

WCF:在嵌套服务调用中保留内部异常