Brian Reindel Brian Reindel - 7 months ago 38
Java Question

ThreadPoolExecutor intermittently allows uncaught exception through to Main thread

In the Runnable tasks that I give to my custom ThreadPoolExecutor, I catch any Throwable. And then instead of throwing the same Exception, I throw a custom RuntimeException. I override the afterExecute(Runnable runnable, Throwable throwable) method in my executor, and as expected, that exception is available to me after execution. It is my understanding that nothing should then happen with that exception, because I've taken care to deal with it. However, intermittently, the exception is being allowed through to the Main thread, which is then printing it to System.err using the Thread.getUncaughtExceptionHandler(). I've validated this by placing the following in my application's main method:

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.err.println("I shouldn't have got here!");
}
});


Now I can easily do nothing in the code above, and prevent the output to System.err, but I would rather figure out why the ThreadPoolExecutor is letting exceptions escape from the tasks I give it. Any thoughts on why this might be happening?

Answer

ThreadPoolExecutor catches and re-throws exception from task:

                try {
                    task.run();
                } catch (RuntimeException x) {
                    thrown = x; throw x;
                } catch (Error x) {
                    thrown = x; throw x;
                } catch (Throwable x) {
                    thrown = x; throw new Error(x);
                } finally {
                    afterExecute(task, thrown);
                }

so exception will be handled by default handler anyway.

If you want to avoid call to default handler then you can wrap your Runnable with FutureTask which maintains exceptions internally or create own wrapper to be able to handle exception in appropriate place.