An Uncaught Exception Handler in Java is a mechanism that allows you to define a global or per-thread strategy for dealing with uncaught exceptions — those that are not caught within the thread’s run()
method. It is part of Java’s Thread
API and is particularly useful in multi-threaded environments where uncaught exceptions would otherwise silently terminate a thread.
Why Use an Uncaught Exception Handler?
When a thread throws an exception and does not catch it, the thread dies — and unless you’ve set up an UncaughtExceptionHandler
, that failure may go unnoticed, especially in production systems. By using this handler:
-
You can log the exception,
-
Alert monitoring systems,
-
Or restart threads/services if needed.
Syntax and Structure
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Default handler caught exception in thread " + t.getName() + ": " + e);
}
});
Code language: JavaScript (javascript)
Or per-thread:
Thread t = new Thread(() -> {
throw new RuntimeException("Something went wrong!");
});
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Exception in thread " + t.getName() + ": " + e);
}
});
Code language: JavaScript (javascript)
How It Works
When a thread terminates due to an uncaught exception:
-
Java checks if the thread has its own handler using
t.getUncaughtExceptionHandler()
. -
If none is set, it checks the default handler via
Thread.getDefaultUncaughtExceptionHandler()
. -
If that is also not set, the JVM handles it by printing the stack trace to stderr.
Example Program
public class UncaughtHandlerExample { public static void main(String[] args) { Thread.setDefaultUncaughtExceptionHandler((thread, exception) -> { System.out.println("Caught by default handler: " + exception.getMessage()); }); Thread t1 = new Thread(() -> { throw new RuntimeException("Unhandled exception in t1"); }); Thread t2 = new Thread(() -> { throw new NullPointerException("Unhandled exception in t2"); }); t1.start(); t2.start(); } }
Use Cases
-
Logging fatal thread crashes
-
Fail-safe recovery mechanisms
-
Graceful shutdown alerts
-
Integration with monitoring tools (e.g., Sentry, New Relic)
 Best Practices
Do | Avoid |
---|---|
Use per-thread handlers for critical tasks | Ignoring thread crashes |
Log all uncaught exceptions with full stack trace | Overloading handler with heavy logic |
Use default handler for general fallback | Restarting threads blindly without state checks |
Uncaught exception handlers are a powerful feature in Java’s concurrency model that allow you to catch and process uncaught exceptions thrown by threads. They help improve error visibility, recovery, and system stability in concurrent applications.