A SwingWorker that doesn’t swallow exceptions

Frustrated by SwingWorker frequently swallowing very important exceptions in my code, I decided to finally try to resolve this. In summary, SwingWorker is a class that will run a task off the event dispatch thread, and then, upon completing the task, run a ‘done’ method on the event dispatch thread. SwingWorker also support intermediate publishing onto the EDT, etc.

The problem is, unless you call get() in the done() method, you won’t know that an exception has occurred. In all of my use cases for SwingWorker, I never call get() in done(). Therefore, I was often-times missing exceptions. That is where SimpleSwingWorker comes in. I come across this code somewhere online, and genericised it to be a bit nicer to work with. Other than that, it is a drop-in replacement for the simple SwingWorker use case I tend to have.

I hope that this is helpful to other people – it certainly is very useful for me!

9 thoughts on “A SwingWorker that doesn’t swallow exceptions”

  1. Line 30 should be:

    throw new RuntimeException(ex.getCause())

    because the ExecutionException *always* wraps the original cause. ExecutionException is merely the mechanism SwingWorker uses to pass the true exception to the done() method.

    1. Alex: To be honest, because I didn’t know of Foxtrot. However, given the SimpleSwingWorker above, and SwingWorker in general, I don’t yet feel the need for any additional libraries. Foxtrot is small at ~35kb, but it’s just one more lib that needs to be justified.

      1. Fair enough, but I find Foxtrot wonderful. I’m using it flawlessly in production code and it perfectly manages not only exceptions but deques UI events while blocking in the code, so code turns out much, much cleaner. I see no reason to ever go back to the mess of SwingWorkers.

  2. Another issue I’ve seen with SwingWorker is that it is common to launch a SwingWorker while a modal dialog is open. If the done method closes the modal dialog, exceptions that are rethrown in the try/catch will not get caught by an uncaught exception handler. The EDT will simple to a stack trace printout since the modal dialog has not been fully closed.

    One alternative I’ve found is to invoke the try/catch block in a SwingUtilities.invokeLater(new Runnable() {
    try/catch the get() method and rethrow the exceptions
    });

    This allows the modal dialog to fully close and then the exception handler will still get the exceptions. Maybe there’s a better way…

  3. Hi,

    Thanks to this code, it’s very helpful 🙂

    I was wondering how to solve this problem and I found your post.

    I already had a class extending SwingWorker to allows to make an operations before the start of the background task and I wondered if I could use your code and mix the two features and present that on my blog (with a link to your blog post and a mention that you’re the author of that part) ?

    Thanks

    Baptiste

  4. Wow, you’ve just saved my life !! It’s been 2 days I’ve tried to find why eclipse console didn’t output a simple null pointer exception (try to substring a null String) I coded, when I found a post telling that maybe SwingWorker could be the cause, and finally I found your SimpleSwingWorker Class !! Thanks so so much !!

Leave a Reply