Question
In Java, what is the simplest and most reliable way to convert the stack trace from an exception into a String representation?
For example, if I have a Throwable and want the full stack trace as text for logging, debugging, or storing somewhere, how can I turn it into a string that looks like the normal printed stack trace?
Throwable error = new RuntimeException("Something went wrong");
// How do I convert this stack trace to a String?
Short Answer
By the end of this page, you will understand how Java stack traces work, why Throwable.getStackTrace() does not directly give you the normal printed stack trace text, and how to correctly convert an exception stack trace into a String using StringWriter and PrintWriter. You will also see common mistakes, practical use cases, and a small mini-project.
Concept
A Java stack trace shows where an error happened and how the program reached that point. It usually includes:
- The exception type
- The error message
- The list of method calls leading to the error
- Sometimes a
Caused bychain for nested exceptions
A common beginner misunderstanding is assuming that Throwable.getStackTrace() returns a printable string. It does not. It returns an array of StackTraceElement objects:
StackTraceElement[] elements = throwable.getStackTrace();
That array contains structured stack-frame data, not the formatted text you normally see in logs.
If you want the familiar multi-line stack trace text, the usual approach is:
- Create a
StringWriter - Wrap it in a
PrintWriter - Call
throwable.printStackTrace(printWriter) - Read the text from the
StringWriter
This matters in real programming because stack traces are often:
- Logged to files
- Sent to monitoring systems
- Stored in error reports
- Returned in development tools
- Attached to API diagnostics in non-production environments
Using the correct approach ensures you preserve the full formatted trace, including nested causes.
Mental Model
Think of a stack trace like a breadcrumb trail showing how your program arrived at a failure.
getStackTrace()gives you the individual breadcrumbs as objects.printStackTrace()gives you the formatted story that humans usually read.
So if you want a readable string, do not just grab the breadcrumbs. Ask Java to write the story into a text buffer, then read that buffer as a string.
Syntax and Examples
The standard Java approach is:
import java.io.PrintWriter;
import java.io.StringWriter;
public class Main {
public static String stackTraceToString(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
throwable.printStackTrace(pw);
return sw.toString();
}
}
Example usage
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0;
System.out.println(result);
} catch (Exception e) {
String trace = stackTraceToString(e);
System.out.println(trace);
}
}
public static String stackTraceToString(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
throwable.printStackTrace(pw);
return sw.toString();
}
}
Why this works
StringWriterstores text in memory.PrintWriterwrites formatted text into thatStringWriter.printStackTrace(...)prints the exception in the same format Java normally uses.sw.toString()gives you the final text.
If you only use getStackTrace()
StackTraceElement[] elements = e.getStackTrace();
System.out.println(elements);
This will not print a readable stack trace. It will usually print something like:
[Ljava.lang.StackTraceElement;@6d311334
That is the array object's default string form, not the formatted stack trace.
Step by Step Execution
Consider this example:
import java.io.PrintWriter;
import java.io.StringWriter;
public class Main {
public static void main(String[] args) {
try {
fail();
} catch (Exception e) {
String trace = stackTraceToString(e);
System.out.println(trace);
}
}
static void fail() {
throw new IllegalArgumentException("Bad input");
}
static String stackTraceToString(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
throwable.printStackTrace(pw);
return sw.toString();
}
}
What happens step by step
main()callsfail().fail()throws anIllegalArgumentException.- Control jumps to the
catchblock inmain(). stackTraceToString(e)is called.- A
StringWriteris created to hold text in memory. - A
PrintWriteris created to write text into theStringWriter. throwable.printStackTrace(pw)writes the full formatted stack trace into the buffer.sw.toString()returns that buffered text as aString.System.out.println(trace)prints the string.
Example output
java.lang.IllegalArgumentException: Bad input
at Main.fail(Main.java:16)
at Main.main(Main.java:8)
The exact line numbers may differ, but the structure will be the same.
Real World Use Cases
Converting a stack trace to a string is useful in many practical situations:
Logging systems
You may want to store the full stack trace in a log message:
logger.error("Request failed: {}", stackTraceToString(e));
Error reporting
Applications often collect error details and send them to a monitoring service:
String errorDetails = stackTraceToString(e);
// send errorDetails to monitoring system
Saving debug information
You might write a stack trace into a file for troubleshooting:
Files.writeString(path, stackTraceToString(e));
Admin tools and diagnostics
A developer-only endpoint or support tool may show recent exception traces.
Background jobs
If a scheduled task fails, you may want to capture the stack trace as text and include it in an email or status report.
Real Codebase Usage
In real Java projects, developers usually do not convert stack traces to strings unless they have a specific reason. Many logging frameworks already accept the exception directly:
logger.error("Job failed", e);
That is often better because the logger can format the exception properly.
Still, converting to a string is common in these patterns:
Validation and diagnostics
When building structured error reports:
Map<String, String> errorReport = new HashMap<>();
errorReport.put("message", e.getMessage());
errorReport.put("stackTrace", stackTraceToString(e));
Guard clauses with detailed failure capture
if (config == null) {
throw new IllegalStateException("Configuration must not be null");
}
If this is caught later, the stack trace string may be attached to a support report.
Error handling pipelines
Some systems normalize exceptions into a common format:
- Error code
- User-safe message
- Internal debug message
- Stack trace string
API responses in development mode
In development, a server might include stack trace text in a debug response. In production, this is usually avoided for security reasons.
Test failure diagnostics
Tests and build tools may capture stack traces as strings to compare, store, or display them in reports.
Common Mistakes
Mistake 1: Printing the array returned by getStackTrace()
Broken code:
System.out.println(e.getStackTrace());
Why it is wrong:
getStackTrace()returns an array- Printing the array directly does not format the stack trace
Better:
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String trace = sw.toString();
Mistake 2: Losing nested causes
Broken approach:
StringBuilder sb = new StringBuilder();
for (StackTraceElement element : e.getStackTrace()) {
sb.append(element).append("\n");
}
Why it is incomplete:
- It may omit the exception header
- It may omit
Caused bychains - It may omit suppressed exceptions
Better:
e.printStackTrace(pw);
Mistake 3: Converting stack traces when the logger already supports exceptions
Less ideal:
logger.error(stackTraceToString(e));
Often better:
logger.error("Operation failed", e);
This keeps the exception object intact for the logging framework.
Mistake 4: Exposing stack traces to end users
Broken idea:
return "Something failed:\n" + stackTraceToString(e);
Why it is risky:
- Stack traces can reveal internal implementation details
- They may expose file paths, class names, or system structure
Better:
- Show a safe user-facing message
- Log or store the stack trace internally
Mistake 5: Forgetting imports
You need:
import java.io.PrintWriter;
import java.io.StringWriter;
Comparisons
| Approach | What it returns | Human-readable | Includes full formatting | Best use |
|---|---|---|---|---|
throwable.getStackTrace() | StackTraceElement[] | Not directly | No | Programmatic inspection |
throwable.printStackTrace() | Prints to stream/writer | Yes | Yes | Console, files, writers |
throwable.printStackTrace(new PrintWriter(sw)) | String via writer buffer | Yes | Yes | Capture as text |
| Manual loop over stack frames | Custom text | Sometimes | Often incomplete | Custom formatting only |
getStackTrace() vs printStackTrace()
- Use
getStackTrace()when you want to inspect individual frames in code. - Use
printStackTrace()when you want the familiar readable output.
String conversion vs direct logging
| Option | When to use |
|---|---|
logger.error("message", e) | Best for normal application logging |
| Convert to string first | Useful for storing, sending, or embedding trace text |
In short:
- Need structured frames? Use
getStackTrace(). - Need readable text? Use
printStackTrace()with aStringWriter.
Cheat Sheet
import java.io.PrintWriter;
import java.io.StringWriter;
public static String stackTraceToString(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
return sw.toString();
}
Key rules
getStackTrace()returnsStackTraceElement[], not a formatted string.printStackTrace(PrintWriter)writes the normal stack trace format.StringWriterlets you capture printed text as a string.- Prefer
logger.error("message", e)when using a logging framework. - Avoid showing stack traces to end users in production.
Useful snippet
try {
// code
} catch (Exception e) {
String trace = stackTraceToString(e);
}
Edge case reminder
Manual formatting may miss:
- exception type
- message
- caused-by exceptions
- suppressed exceptions
FAQ
Why doesn't getStackTrace() return a string?
Because Java separates the raw stack frame data from the formatted printed output. getStackTrace() gives structured data, not display text.
What is the standard way to convert a stack trace to a string in Java?
Use StringWriter and PrintWriter, then call throwable.printStackTrace(printWriter).
Is printStackTrace() the same as getStackTrace()?
No. getStackTrace() returns an array of stack frames. printStackTrace() produces the human-readable formatted trace.
Should I store stack traces in a database?
Sometimes, for diagnostics or error reporting. But avoid storing sensitive information unless necessary, and be careful with database size.
Can I manually join the StackTraceElement values?
You can, but it is often incomplete and may miss the exception message, nested causes, and suppressed exceptions.
Is it better to log the exception directly?
Usually yes. Most logging frameworks can format exceptions correctly when you pass the Throwable directly.
Can I use this for any Throwable, not just Exception?
Yes. It works for Exception, RuntimeException, Error, and any subclass of Throwable.
Mini Project
Description
Build a small Java utility that safely captures exception details as text for debugging and reporting. This demonstrates the difference between exception objects, stack frame arrays, and readable stack trace strings. It also mirrors a common real-world helper method used in services, background jobs, and diagnostic tools.
Goal
Create a reusable method that converts any Throwable into a readable stack trace string and use it in a simple demo program.
Requirements
- Create a method that accepts a
Throwableand returns aString - Trigger an exception intentionally in a demo program
- Catch the exception and convert its stack trace to a string
- Print the resulting string to the console
- Keep the solution in plain Java using standard library classes only
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.