Monday, March 28, 2011

Catching Exception in Threads

Java 5 introduced a new way to catch unexpected exceptions: Thread.UncaughtExceptionHandler. This is an interface with the following API:
public interface UncaughtExceptionHandler {
void uncaughtException(Thread t, Throwable e);
}
Your job is to write a class that implements this interface. You then register your implementation on a per-thread basis, or globally for every thread. To register your handler for a single thread you do something like this:
Thread.currentThread().setUncaughtExceptionHandler(new MyExceptionHandler());
To register your handler for every thread, do this:
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
Notice that setDefaultUncaughtExceptionHandler(...) is a static method in the Thread class, while setUncaughtExceptionHandler(...) is a non-static method.

Simple enough. Let’s add an uncaught exception handler.
MyExceptionHandler
Here is a simple uncaught exception handler that shows the exception message in a dialog box.
public class MyExceptionHandler implements Thread.UncaughtExceptionHandler {

public void uncaughtException(final Thread t, final Throwable e) {
if (SwingUtilities.isEventDispatchThread()) {
showException(t, e);
} else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showException(t, e);
}
});
}
}

private void showException(Thread t, Throwable e) {
String msg = String.format("Unexpected problem on thread %s: %s",
t.getName(), e.getMessage());

logException(t, e);

// note: in a real app, you should locate the currently focused frame
// or dialog and use it as the parent. In this example, I'm just passing
// a null owner, which means this dialog may get buried behind
// some other screen.
JOptionPane.showMessageDialog(null, msg);
}

private void logException(Thread t, Throwable e) {
// todo: start a thread that sends an email, or write to a log file, or
// send a JMS message...whatever
}
}
To use this handler, you must register it. Simply modify the code as follows:
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());

...
Now, whenever an “unexpected” exception occurs, MyExceptionHandler kicks in and shows this lovely dialog box:

No comments:

Post a Comment