1

I have an inner class that extends Thread

private class TestStart extends Thread { public void run() { try { startServer(); } catch (Exception e) { /// How to handle it? } } } 

The caller in the main thread:

public void start() throws Exception { Thread st = new TestStart(); st.start(); } 

Method startServer() throws Exception by its API, so I have to use try-catch as Thread.run() does not "throws" exception in method definition. I need to bubble up the caught exception into the main thread to handle it. Is there an easy way to do it? Thanks

2

3 Answers 3

4

If you use an ExecutorService instead of using raw threads, you can be notified of uncaught exceptions:

class MyCallable implements Callable<Void> { @Override public Void call() throws Exception { // Do something - you don't need to catch Exception as Callable throws it. // ... return null; // A return is necessary from a Callable. } } 

Create an executor service somewhere, e.g.:

ExecutorService executor = Executors.newFixedThreadPool(1); 

Then, in the code where you start the thread:

Future<?> future = executor.submit(new MyCallable()); try { future.get(); // Blocks until the Callable completes. } catch (ExecutionException e) { // You reach here if an exception is thrown in the Callable - // The exception is accessible via e.getCause(). } 
Sign up to request clarification or add additional context in comments.

Comments

1

There is a few possible solutions. For example:

  1. Use setUncaughtExceptionHandler()/setDefaultUncaughtExceptionHandler() and change your try/catch

    try { startServer(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } 
  2. Or use your custom listener

    private class TestStart extends Thread { private final ServerStateListener lnr; TestStart(ServerStateListener lnr) { this.lnr = lnr; } public void run() { try { startServer(); lnr.onServerStarted(); } catch (Exception e) { lnr.onServerStoppedByError(e); } } } 
  3. Or just save Exception and read it after .join

    private class TestStart extends Thread { private Exception error; // if you start and join and read this property within one thread, you don't need to use volatile, otherwise do it for safe publication public void run() { try { startServer(); } catch (Exception e) { error = e; } } public Exception getError() { return error; } } 
  4. Or use ExecutorService/Callable instead of your own thread as Andy suggested.

Comments

0

Set a new exception handler on your Thread.

 st.setDefaultUncaughtExceptionHandler(new Thread. UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { System.out.println(t + " throws exception: " + e); } }); 

And place that code before your start();

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.