Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX's task seem to consume exceptions. Is it a bug or a feature?

Tags:

Consider this code:

Thread.setDefaultUncaughtExceptionHandler((Thread t, Throwable e) -> {     System.out.println("An exception occurred!"); });  // set the exception handler for the JavaFX application thread Thread.currentThread().setUncaughtExceptionHandler((Thread t, Throwable e) -> {     System.out.println("An exception occurred!"); });  Task<?> task = new Task() {     @Override     public Void call() throws Exception {         throw new RuntimeException("foobar");     }; };  new Thread(task).start(); 

If we run the code the runtime exception never triggers the default exception handler but is instead consumed by the task. The only way to counteract this that I found is to rethrow the exception in task.setOnFailed:

task.setOnFailed((WorkerStateEvent t) -> {     throw new RuntimeException(task.getException()); }); 

Since JavaFX 8 now has support for the UncaughtExceptionHandler why isn't the exception propagated to the exception handler?

like image 498
user555 Avatar asked Sep 16 '14 07:09

user555


1 Answers

Inside the Task.call() method just throw the exception and add a ChangeListener to the task like this:

task.exceptionProperty().addListener((observable, oldValue, newValue) ->  {   if(newValue != null) {     Exception ex = (Exception) newValue;     ex.printStackTrace();   } }); 

Then, after the task failed with the exception, you get notified by the listener which exception was thrown during execution. You can easily exchange the line ex.printStackTrace(); with an Alert if you are in the JavaFX Execution Thread.

like image 124
akmonius Avatar answered Sep 19 '22 01:09

akmonius