I've been struggling with the usability problem of SwingWorker eating any exceptions thrown in the background task, for example, described on this SO thread.  That thread gives a nice description of the problem, but doesn't discuss recovering the original exception.
The applet I've been handed needs to propagate the exception upwards.  But I haven't been able to even catch it.  I'm using the SimpleSwingWorker wrapper class from this blog entry specifically to try and address this issue.  It's a fairly small class but I'll repost it at the end here just for reference.
The calling code looks broadly like
try {
    // lots of code here to prepare data, finishing with
    SpecialDataHelper helper = new SpecialDataHelper(...stuff...);
    helper.execute();
} catch (Throwable e) {
    // used "Throwable" here in desperation to try and get
    // anything at all to match, including unchecked exceptions
    //
    // no luck, this code is never ever used :-(
}
The wrappers:
class SpecialDataHelper extends SimpleSwingWorker {
    public SpecialDataHelper (SpecialData sd) {
        this.stuff = etc etc etc;
    }
    public Void doInBackground() throws Exception {
        OurCodeThatThrowsACheckedException(this.stuff);
        return null;
    }
    protected void done() {
        // called only when successful
        // never reached if there's an error
    }
}
The feature of SimpleSwingWorker is that the actual SwingWorker's done()/get() methods are automatically called.  This, in theory, rethrows any exceptions that happened in the background.  In practice, nothing is ever caught, and I don't even know why.
The SimpleSwingWorker class, for reference, and with nothing elided for brevity:
import java.util.concurrent.ExecutionException;
import javax.swing.SwingWorker;
/**
 * A drop-in replacement for SwingWorker<Void,Void> but will not silently
 * swallow exceptions during background execution.
 *
 * Taken from http://jonathangiles.net/blog/?p=341 with thanks.
 */
public abstract class SimpleSwingWorker {
    private final SwingWorker<Void,Void> worker =
        new SwingWorker<Void,Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                SimpleSwingWorker.this.doInBackground();
                return null;
            }
            @Override
            protected void done() {
                // Exceptions are lost unless get() is called on the
                // originating thread.  We do so here.
                try {
                    get();
                } catch (final InterruptedException ex) {
                    throw new RuntimeException(ex);
                } catch (final ExecutionException ex) {
                    throw new RuntimeException(ex.getCause());
                }
                SimpleSwingWorker.this.done();
            }
    };
    public SimpleSwingWorker() {}
    protected abstract Void doInBackground() throws Exception;
    protected abstract void done();
    public void execute() {
        worker.execute();
    }
}