How can I convert a stack trace to a string?

JavaStack TraceTostring

Java Problem Overview


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

Java Solutions


Solution 1 - Java

Use Throwable.printStackTrace(PrintWriter pw) to send the stack trace to an appropriate writer.

import java.io.StringWriter;
import java.io.PrintWriter;

// ...

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); // stack trace as a string
System.out.println(sStackTrace);

Solution 2 - Java

One can use the following method to convert an Exception stack trace to String. This class is available in Apache commons-lang which is most common dependent library with many popular open sources

org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)

Solution 3 - Java

This should work:

StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();

Solution 4 - Java

If you are developing for Android, a far easier way is to use this:

import android.util.Log;

String stackTrace = Log.getStackTraceString(exception); 

The format is the same as getStacktrace, for e.g.

> 09-24 16:09:07.042: I/System.out(4844): java.lang.NullPointerException > 09-24 16:09:07.042: I/System.out(4844): at com.temp.ttscancel.MainActivity.onCreate(MainActivity.java:43) > 09-24 16:09:07.042: I/System.out(4844): at android.app.Activity.performCreate(Activity.java:5248) > 09-24 16:09:07.043: I/System.out(4844): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110) > 09-24 16:09:07.043: I/System.out(4844): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162) > 09-24 16:09:07.043: I/System.out(4844): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) > 09-24 16:09:07.043: I/System.out(4844): at android.app.ActivityThread.access$800(ActivityThread.java:139) > 09-24 16:09:07.043: I/System.out(4844): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210) > 09-24 16:09:07.043: I/System.out(4844): at android.os.Handler.dispatchMessage(Handler.java:102) > 09-24 16:09:07.043: I/System.out(4844): at android.os.Looper.loop(Looper.java:136) > 09-24 16:09:07.044: I/System.out(4844): at android.app.ActivityThread.main(ActivityThread.java:5097) > 09-24 16:09:07.044: I/System.out(4844): at java.lang.reflect.Method.invokeNative(Native Method) > 09-24 16:09:07.044: I/System.out(4844): at java.lang.reflect.Method.invoke(Method.java:515) > 09-24 16:09:07.044: I/System.out(4844): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) > 09-24 16:09:07.044: I/System.out(4844): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)

Solution 5 - Java

Guava's Throwables class

If you have the actual Throwable instance, Google Guava provides Throwables.getStackTraceAsString().

Example:

String s = Throwables.getStackTraceAsString ( myException ) ;

Solution 6 - Java

WARNING: Does not include cause (which is usually the useful bit!)

public String stackTraceToString(Throwable e) {
    StringBuilder sb = new StringBuilder();
    for (StackTraceElement element : e.getStackTrace()) {
        sb.append(element.toString());
        sb.append("\n");
    }
    return sb.toString();
}

Solution 7 - Java

For me the cleanest and easiest way was:

import java.util.Arrays;
Arrays.toString(e.getStackTrace());

Solution 8 - Java

public static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    return sw.toString();
}

Solution 9 - Java

The following code allows you to get the entire stackTrace with a String format, without using APIs like log4J or even java.util.Logger:

catch (Exception e) {
	StackTraceElement[] stack = e.getStackTrace();
	String exception = "";
	for (StackTraceElement s : stack) {
	    exception = exception + s.toString() + "\n\t\t";
	}
    System.out.println(exception);
    // then you can send the exception string to a external file.
}

Solution 10 - Java

Print the stack trace to a PrintStream, then convert it to a String:

// ...
 
catch (Exception e)
{
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    e.printStackTrace(new PrintStream(out));
    String str = new String(out.toByteArray());
    
    System.out.println(str);
}

Solution 11 - Java

Here is a version that is copy-pastable directly into code:

import java.io.StringWriter; 
import java.io.PrintWriter;

//Two lines of code to get the exception into a StringWriter
StringWriter sw = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(sw));

//And to actually print it
logger.info("Current stack trace is:\n" + sw.toString());

Or, in a catch block

} catch (Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    logger.info("Current stack trace is:\n" + sw.toString());
}

Solution 12 - Java

Arrays.toString(thrown.getStackTrace())

Is the easiest way to convert the result into String I am using this in my program to print the stack trace

LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});

Solution 13 - Java

Kotlin >= 1.4

Use the built-in function stackTraceToString() on a Throwable.

Kotlin < 1.4

Extending the Throwable class will give you the String property error.stackTraceString:

val Throwable.stackTraceString: String
  get() {
    val sw = StringWriter()
    val pw = PrintWriter(sw)
    this.printStackTrace(pw)
    return sw.toString()
  }

Solution 14 - Java

if you are using Java 8, try this

Arrays.stream(e.getStackTrace())
                .map(s->s.toString())
                .collect(Collectors.joining("\n"));

you can find the code for getStackTrace() function provided by Throwable.java as :

public StackTraceElement[] getStackTrace() {
    return getOurStackTrace().clone();
}

and for StackTraceElement, it provides toString() as follows:

public String toString() {
    return getClassName() + "." + methodName +
        (isNativeMethod() ? "(Native Method)" :
         (fileName != null && lineNumber >= 0 ?
          "(" + fileName + ":" + lineNumber + ")" :
          (fileName != null ?  "("+fileName+")" : "(Unknown Source)")));
}

So just join the StackTraceElement with "\n".

Solution 15 - Java

Printing stack trace to string

import java.io.PrintWriter;
import java.io.StringWriter;

public class StackTraceUtils {
	public static String stackTraceToString(StackTraceElement[] stackTrace) {
		StringWriter sw = new StringWriter();
		printStackTrace(stackTrace, new PrintWriter(sw));
		return sw.toString();
	}
	public static void printStackTrace(StackTraceElement[] stackTrace, PrintWriter pw) {
		for(StackTraceElement stackTraceEl : stackTrace) {
			pw.println(stackTraceEl);
		}
	}
}

It's useful when you want to print the current thread stack trace without creating instance of Throwable - but note that creating new Throwable and getting stack trace from there is actually faster and cheaper than calling Thread.getStackTrace.

Solution 16 - Java

private String getCurrentStackTraceString() {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    return Arrays.stream(stackTrace).map(StackTraceElement::toString)
            .collect(Collectors.joining("\n"));
}

Solution 17 - Java

Code from Apache Commons Lang 3.4 ([JavaDoc][1]):

public static String getStackTrace(final Throwable throwable) {
    final StringWriter sw = new StringWriter();
    final PrintWriter pw = new PrintWriter(sw, true);
    throwable.printStackTrace(pw);
    return sw.getBuffer().toString();
}

The difference with the other answers is that it uses autoFlush on the PrintWriter. [1]: https://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/exception/ExceptionUtils.html#getStackTrace(java.lang.Throwable)

Solution 18 - Java

The clever sniping in the first set of comments was very amusing, but it really depends on what you are trying to do. If you don't already have the correct library, then 3 lines of code (as in D. Wroblewski's answer) is perfect. OTOH, if you already have the apache.commons library (as most large projects will), then Amar's answer is shorter. OK, it might take you ten minutes to get the library and install it correctly (less than one if you know what you're doing). But the clock is ticking, so you may not have the time to spare. Jarek Przygódzki had an interesting caveat--"If you don't need nested exceptions".

But what if I do need the full stack traces, nested and all? In that case, the secret is to use apache.common's getFullStackTrace (see http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html#getFullStackTrace%28java.lang.Throwable%29)

It saved my bacon. Thanks, Amar, for the hint!

Solution 19 - Java

Without java.io.* it can be done like this.

String trace = e.toString() + "\n";                     

for (StackTraceElement e1 : e.getStackTrace()) {
    trace += "\t at " + e1.toString() + "\n";
}   

And then the trace variable holds your stack trace. Output also holds the initial cause, the output is identical to printStackTrace()

Example, printStackTrace() yields:

java.io.FileNotFoundException: / (Is a directory)
	at java.io.FileOutputStream.open0(Native Method)
	at java.io.FileOutputStream.open(FileOutputStream.java:270)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
	at Test.main(Test.java:9)

The trace String holds, when printed to stdout

java.io.FileNotFoundException: / (Is a directory)
	 at java.io.FileOutputStream.open0(Native Method)
	 at java.io.FileOutputStream.open(FileOutputStream.java:270)
	 at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
	 at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
	 at Test.main(Test.java:9)

Solution 20 - Java

With Java 8 Stream API you can do something like this:

Stream
	.of(throwable.getStackTrace())
	.map(StackTraceElement::toString)
	.collect(Collectors.joining("\n"));

It will take array of stack trace elements, convert them to string and join into multiline string.

Solution 21 - Java

an exapansion on Gala's answer that will also include the causes for the exception:

private String extrapolateStackTrace(Exception ex) {
	Throwable e = ex;
	String trace = e.toString() + "\n";
	for (StackTraceElement e1 : e.getStackTrace()) {
		trace += "\t at " + e1.toString() + "\n";
	}
	while (e.getCause() != null) {
		e = e.getCause();
		trace += "Cause by: " + e.toString() + "\n";
		for (StackTraceElement e1 : e.getStackTrace()) {
			trace += "\t at " + e1.toString() + "\n";
		}
	}
	return trace;
}

Solution 22 - Java

Scala version

def stackTraceToString(e: Exception): String = {
  import java.io.PrintWriter
  val sw = new StringWriter()
  e.printStackTrace(new PrintWriter(sw))
  sw.toString
}

Solution 23 - Java

The solution is to convert the stackTrace of array to string data type. See the following example:

import java.util.Arrays;

try{
        
}catch(Exception ex){
    String stack = Arrays.toString(ex.getStackTrace());
    System.out.println("stack "+ stack);
}

Solution 24 - Java

If you don't want to use an external library and you're not developing [for Android](http://developer.android.com/reference/android/util/Log.html#getStackTraceString(java.lang.Throwable) "Android Log.getStackTraceString(java.lang.Throwable)"), you could create an ['extension' method](https://stackoverflow.com/a/25818617/465942 "Difference between printStackTrace() and toString()") like this:

public static String getStackTraceString(Throwable e) {
    return getStackTraceString(e, "");
}

private static String getStackTraceString(Throwable e, String indent) {
    StringBuilder sb = new StringBuilder();
    sb.append(e.toString());
    sb.append("\n");

    StackTraceElement[] stack = e.getStackTrace();
    if (stack != null) {
        for (StackTraceElement stackTraceElement : stack) {
            sb.append(indent);
            sb.append("\tat ");
            sb.append(stackTraceElement.toString());
            sb.append("\n");
        }
    }

    Throwable[] suppressedExceptions = e.getSuppressed();
    // Print suppressed exceptions indented one level deeper.
    if (suppressedExceptions != null) {
        for (Throwable throwable : suppressedExceptions) {
            sb.append(indent);
            sb.append("\tSuppressed: ");
            sb.append(getStackTraceString(throwable, indent + "\t"));
        }
    }

    Throwable cause = e.getCause();
    if (cause != null) {
        sb.append(indent);
        sb.append("Caused by: ");
        sb.append(getStackTraceString(cause, indent));
    }

    return sb.toString();
}

Solution 25 - Java

My oneliner to convert stack trace to the enclosed multi-line string:

Stream.of(e.getStackTrace()).map((a) -> a.toString()).collect(Collectors.joining("\n", "[", "]"))

Easy to pass to the logger "as is".

Solution 26 - Java

 import java.io.PrintWriter;
import java.io.StringWriter;

public class PrintStackTrace {

    public static void main(String[] args) {

        try {
            int division = 0 / 0;
        } catch (ArithmeticException e) {
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            String exceptionAsString = sw.toString();
            System.out.println(exceptionAsString);
        }
    }
}

When you run the program, the output will be something similar:

java.lang.ArithmeticException: / by zero
at PrintStackTrace.main(PrintStackTrace.java:9)

Solution 27 - Java

Old question, but I would just like to add the special case where you don't want to print all the stack, by removing some parts you are not actually interested in, excluding certain classes or packages.

Instead of a PrintWriter use a SelectivePrintWriter:

// This filters out this package and up.
String packageNameToFilter = "org.springframework";
 
StringWriter sw = new StringWriter();
PrintWriter pw = new SelectivePrintWriter(sw, packageNameToFilter);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); 
System.out.println(sStackTrace);

Where the SelectivePrintWriter class is given by:

public class SelectivePrintWriter extends PrintWriter {
    private boolean on = true;
    private static final String AT = "\tat";
    private String internal;

    public SelectivePrintWriter(Writer out, String packageOrClassName) {
        super(out);
        internal = "\tat " + packageOrClassName;
    }

    public void println(Object obj) {
        if (obj instanceof String) {
            String txt = (String) obj;
            if (!txt.startsWith(AT)) on = true;
            else if (txt.startsWith(internal)) on = false;
            if (on) super.println(txt);
        } else {
            super.println(obj);
        }
    }
}

Please note this class may be easily adapted to filter out by Regex, contains or other criteria. Also note it depends upon Throwable implementation details (not likely to change, but still).

Solution 28 - Java

Warning: This may be a bit off topic, but oh well... ;)

I don't know what the original posters reason was for wanting the stack trace as string in the first place. When the stack trace should end up in an SLF4J/Logback LOG, but no exception was or should be thrown here's what I do:

public void remove(List<String> ids) {
    if(ids == null || ids.isEmpty()) {
        LOG.warn(
            "An empty list (or null) was passed to {}.remove(List). " +
            "Clearly, this call is unneccessary, the caller should " + 
            "avoid making it. A stacktrace follows.", 
            getClass().getName(),
            new Throwable ("Stacktrace")
        );
        
        return;
    }

    // actual work, remove stuff
}

I like it because it does not require an external library (other than your logging backend, which will be in place most of the time anyway, of course).

Solution 29 - Java

Few options

  1. StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); String exceptionAsString = sw.toString();

  2. Using Google Guava lib String stackTrace = Throwables.getStackTraceAsString ( myException ) ;

  3. org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)

Solution 30 - Java

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.<init>(Unknown Source)
	at com.gmail.br45entei.Example.main(Example.java:32)

Solution 31 - Java

I wonder why no one mentioned ExceptionUtils.getStackFrames(exception)

For me it's the most convenient way to dump stacktrace with all its causes to the end:

String.join("\n", ExceptionUtils.getStackFrames(exception));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionripper234View Question on Stackoverflow
Solution 1 - JavaBrian AgnewView Answer on Stackoverflow
Solution 2 - JavaamarView Answer on Stackoverflow
Solution 3 - JavaD. WroblewskiView Answer on Stackoverflow
Solution 4 - JavaVicky KapadiaView Answer on Stackoverflow
Solution 5 - JavastumbavView Answer on Stackoverflow
Solution 6 - JavajqnoView Answer on Stackoverflow
Solution 7 - JavaVladas DiržysView Answer on Stackoverflow
Solution 8 - JavaAkira YamamotoView Answer on Stackoverflow
Solution 9 - JavadumondericView Answer on Stackoverflow
Solution 10 - JavaBaked InhalfView Answer on Stackoverflow
Solution 11 - JavaroubleView Answer on Stackoverflow
Solution 12 - JavaRamanan DurairajView Answer on Stackoverflow
Solution 13 - Javavonox7View Answer on Stackoverflow
Solution 14 - JavaPengcheng ZhangView Answer on Stackoverflow
Solution 15 - JavaJarek PrzygódzkiView Answer on Stackoverflow
Solution 16 - JavaeddyrokrView Answer on Stackoverflow
Solution 17 - JavaIvanRFView Answer on Stackoverflow
Solution 18 - JavaTihamerView Answer on Stackoverflow
Solution 19 - JavaGalaView Answer on Stackoverflow
Solution 20 - JavaivanjermakovView Answer on Stackoverflow
Solution 21 - Javaido flaxView Answer on Stackoverflow
Solution 22 - JavasamthebestView Answer on Stackoverflow
Solution 23 - JavaJorge SantosView Answer on Stackoverflow
Solution 24 - JavaKapéView Answer on Stackoverflow
Solution 25 - JavaAndrey LebedenkoView Answer on Stackoverflow
Solution 26 - JavaPrakhar NigamView Answer on Stackoverflow
Solution 27 - JavaMarcGView Answer on Stackoverflow
Solution 28 - JavaAlexander WesselView Answer on Stackoverflow
Solution 29 - JavaEricView Answer on Stackoverflow
Solution 30 - JavaBrian_EnteiView Answer on Stackoverflow
Solution 31 - JavaAndrey SarulView Answer on Stackoverflow