How can I convert a stack trace to a string?

前端 未结 30 1490
再見小時候
再見小時候 2020-11-22 14:51

What is the easiest way to convert the result of Throwable.getStackTrace() to a string that depicts the stacktrace?

30条回答
  •  旧巷少年郎
    2020-11-22 15:04

    I wrote a few methods for this a while ago, so I figured why not throw my two cents at this.

    /** @param stackTraceElements The elements to convert
     * @return The resulting string */
    public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements) {
        return stackTraceElementsToStr(stackTraceElements, "\n");
    }
    
    /** @param stackTraceElements The elements to convert
     * @param lineSeparator The line separator to use
     * @return The resulting string */
    public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
        return stackTraceElementsToStr(stackTraceElements, lineSeparator, "");
    }
    
    /** @param stackTraceElements The elements to convert
     * @param lineSeparator The line separator to use
     * @param padding The string to be used at the start of each line
     * @return The resulting string */
    public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
        String str = "";
        if(stackTraceElements != null) {
            for(StackTraceElement stackTrace : stackTraceElements) {
                str += padding + (!stackTrace.toString().startsWith("Caused By") ? "\tat " : "") + stackTrace.toString() + lineSeparator;
            }
        }
        return str;
    }
    
    /** @param stackTraceElements The elements to convert
     * @return The resulting string */
    public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements) {
        return stackTraceCausedByElementsOnlyToStr(stackTraceElements, "\n");
    }
    
    /** @param stackTraceElements The elements to convert
     * @param lineSeparator The line separator to use
     * @return The resulting string */
    public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
        return stackTraceCausedByElementsOnlyToStr(stackTraceElements, lineSeparator, "");
    }
    
    /** @param stackTraceElements The elements to convert
     * @param lineSeparator The line separator to use
     * @param padding The string to be used at the start of each line
     * @return The resulting string */
    public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
        String str = "";
        if(stackTraceElements != null) {
            for(StackTraceElement stackTrace : stackTraceElements) {
                str += (!stackTrace.toString().startsWith("Caused By") ? "" : padding + stackTrace.toString() + lineSeparator);
            }
        }
        return str;
    }
    
    /** @param e The {@link Throwable} to convert
     * @return The resulting String */
    public static final String throwableToStrNoStackTraces(Throwable e) {
        return throwableToStrNoStackTraces(e, "\n");
    }
    
    /** @param e The {@link Throwable} to convert
     * @param lineSeparator The line separator to use
     * @return The resulting String */
    public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator) {
        return throwableToStrNoStackTraces(e, lineSeparator, "");
    }
    
    /** @param e The {@link Throwable} to convert
     * @param lineSeparator The line separator to use
     * @param padding The string to be used at the start of each line
     * @return The resulting String */
    public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator, String padding) {
        if(e == null) {
            return "null";
        }
        String str = e.getClass().getName() + ": ";
        if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
            str += e.getMessage() + lineSeparator;
        } else {
            str += lineSeparator;
        }
        str += padding + stackTraceCausedByElementsOnlyToStr(e.getStackTrace(), lineSeparator, padding);
        for(Throwable suppressed : e.getSuppressed()) {
            str += padding + throwableToStrNoStackTraces(suppressed, lineSeparator, padding + "\t");
        }
        Throwable cause = e.getCause();
        while(cause != null) {
            str += padding + "Caused by:" + lineSeparator + throwableToStrNoStackTraces(e.getCause(), lineSeparator, padding);
            cause = cause.getCause();
        }
        return str;
    }
    
    /** @param e The {@link Throwable} to convert
     * @return The resulting String */
    public static final String throwableToStr(Throwable e) {
        return throwableToStr(e, "\n");
    }
    
    /** @param e The {@link Throwable} to convert
     * @param lineSeparator The line separator to use
     * @return The resulting String */
    public static final String throwableToStr(Throwable e, String lineSeparator) {
        return throwableToStr(e, lineSeparator, "");
    }
    
    /** @param e The {@link Throwable} to convert
     * @param lineSeparator The line separator to use
     * @param padding The string to be used at the start of each line
     * @return The resulting String */
    public static final String throwableToStr(Throwable e, String lineSeparator, String padding) {
        if(e == null) {
            return "null";
        }
        String str = padding + e.getClass().getName() + ": ";
        if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
            str += e.getMessage() + lineSeparator;
        } else {
            str += lineSeparator;
        }
        str += padding + stackTraceElementsToStr(e.getStackTrace(), lineSeparator, padding);
        for(Throwable suppressed : e.getSuppressed()) {
            str += padding + "Suppressed: " + throwableToStr(suppressed, lineSeparator, padding + "\t");
        }
        Throwable cause = e.getCause();
        while(cause != null) {
            str += padding + "Caused by:" + lineSeparator + throwableToStr(e.getCause(), lineSeparator, padding);
            cause = cause.getCause();
        }
        return str;
    }
    

    Example:

    try(InputStream in = new FileInputStream(file)) {
        ...
    } catch(IOException e) {
        String exceptionToString = throwableToStr(e);
        someLoggingUtility.println(exceptionToString);
        ...
    }
    

    Prints:

    java.io.FileNotFoundException: C:\test.txt (The system cannot find the file specified)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(Unknown Source)
        at java.io.FileInputStream.(Unknown Source)
        at com.gmail.br45entei.Example.main(Example.java:32)
    

提交回复
热议问题