Suppose I have a class defining a big block of work to be done, that can produce several checked Exceptions.
class WorkerClass{
public Output work(Input input) throws InvalidInputException, MiscalculationException {
...
}
}
Now suppose I have a GUI of some sort that can call this class. I use a SwingWorker to delegate the task.
Final Input input = getInput();
SwingWorker<Output, Void> worker = new SwingWorker<Output, Void>() {
@Override
protected Output doInBackground() throws Exception {
return new WorkerClass().work(input);
}
};
How can I handle the possible exceptions thrown from the SwingWorker? I want to differentiate between the Exceptions of my worker class (InvalidInputException and MiscalculationException), but the ExecutionException wrapper complicates things. I only want to handle these Exceptions - an OutOfMemoryError should not be caught.
try{
worker.execute();
worker.get();
} catch(InterruptedException e){
//Not relevant
} catch(ExecutionException e){
try{
throw e.getCause(); //is a Throwable!
} catch(InvalidInputException e){
//error handling 1
} catch(MiscalculationException e){
//error handling 2
}
}
//Problem: Since a Throwable is thrown, the compiler demands a corresponding catch clause.
catch (ExecutionException e) {
Throwable ee = e.getCause ();
if (ee instanceof InvalidInputException)
{
//error handling 1
} else if (ee instanceof MiscalculationException e)
{
//error handling 2
}
else throw e; // Not ee here
}
You could use an ugly (smart?) hack to convert the throwable into an unchecked exception. The advantage is that the calling code will receive whatever exception was thrown by your worker thread, whether checked or unchecked, but you don't have to change the signature of your method.
try {
future.get();
} catch (InterruptedException ex) {
} catch (ExecutionException ex) {
if (ex.getCause() instanceof InvalidInputException) {
//do your stuff
} else {
UncheckedThrower.throwUnchecked(ex.getCause());
}
}
With UncheckedThrower
defined as:
class UncheckedThrower {
public static <R> R throwUnchecked(Throwable t) {
return UncheckedThrower.<RuntimeException, R>trhow0(t);
}
@SuppressWarnings("unchecked")
private static <E extends Throwable, R> R trhow0(Throwable t) throws E {
throw (E) t;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With