Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly catch RuntimeExceptions from Executors?

Say that I have the following code:

ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(myRunnable); 

Now, if myRunnable throws a RuntimeExcpetion, how can I catch it? One way would be to supply my own ThreadFactory implementation to newSingleThreadExecutor() and set custom uncaughtExceptionHandlers for the Threads that come out of it. Another way would be to wrap myRunnable to a local (anonymous) Runnable that contains a try-catch -block. Maybe there are other similar workarounds too. But... somehow this feels dirty, I feel that it shouldn't be this complicated. Is there a clean solution?

like image 929
Joonas Pulakka Avatar asked Nov 06 '09 14:11

Joonas Pulakka


People also ask

Can you catch runtime exceptions?

Runtime exceptions can occur anywhere in a program, and in a typical one they can be very numerous. Having to add runtime exceptions in every method declaration would reduce a program's clarity. Thus, the compiler does not require that you catch or specify runtime exceptions (although you can).

How do you catch an exception in a thread?

Exceptions are caught by handlers(here catch block). Exceptions are caught by handlers positioned along with the thread's method invocation stack. If the calling method is not prepared to catch the exception, it throws the exception up to its calling method and so on.

Is runtime exception caught by exception?

The Runtime Exception is the parent class in all exceptions of the Java programming language that are expected to crash or break down the program or application when they occur. Unlike exceptions that are not considered as Runtime Exceptions, Runtime Exceptions are never checked.


2 Answers

The clean workaround is to use ExecutorService.submit() instead of execute(). This returns you a Future which you can use to retrieve the result or exception of the task:

ExecutorService executor = Executors.newSingleThreadExecutor(); Runnable task = new Runnable() {   public void run() {     throw new RuntimeException("foo");   } };  Future<?> future = executor.submit(task); try {   future.get(); } catch (ExecutionException e) {   Exception rootException = e.getCause(); } 
like image 182
skaffman Avatar answered Oct 05 '22 22:10

skaffman


Decorate the runnable in another runnable which catches the runtime exceptions and handles them:

public class REHandler implements Runnable {     Runnable delegate;     public REHandler (Runnable delegate) {         this.delegate = delegate;     }     public void run () {         try {             delegate.run ();         } catch (RuntimeException e) {             ... your fancy error handling here ...         }     } }  executor.execute(new REHandler (myRunnable)); 
like image 21
Aaron Digulla Avatar answered Oct 05 '22 20:10

Aaron Digulla