JavaFX 2 - Catching all runtime exceptions

后端 未结 3 652
傲寒
傲寒 2020-12-03 17:57

I tried

Thread.setDefaultUncaughtExceptionHandler...


in the main, and also in the start(Stage primaryStage) method. It ain\'t wor

相关标签:
3条回答
  • 2020-12-03 18:14

    If you check the code for Platform.runLater() (see below), you will see that the exceptions are swallowed (lines 146 / 147), so a default uncaught exception handler won't be able to catch them - based on that piece of code, I don't think you have any options but to include try/catch blocks in your runnables.

    Note that this issue has been reported (requires login - registration is free) and should be fixed in Lombard (= Java FX 8.0 to be released with Java 8 next year).

    You could alternatively create a utility method and call

    Platform.runLater(getFxWrapper(yourRunnable));
    
    public static Runnable getFxWrapper(final Runnable r) {
        return new Runnable() {
    
            @Override
            public void run() {
                try {
                    r.run();
                } catch (Exception e) {
                    //here you probably want to log something
                    System.out.println("Found an exception");
                }
            }
        };
    }
    

    Code of Platform.runLater:

      120     private static void runLater(final Runnable r, boolean exiting) {
      121         if (!initialized.get()) {
      122             throw new IllegalStateException("Toolkit not initialized");
      123         }
      124 
      125         pendingRunnables.incrementAndGet();
      126         waitForStart();
      127 
      128         if (SystemProperties.isDebug()) {
      129             Toolkit.getToolkit().pauseCurrentThread();
      130         }
      131 
      132         synchronized (runLaterLock) {
      133             if (!exiting && toolkitExit.get()) {
      134                 // Don't schedule a runnable after we have exited the toolkit
      135                 pendingRunnables.decrementAndGet();
      136                 return;
      137             }
      138 
      139             Toolkit.getToolkit().defer(new Runnable() {
      140                 @Override public void run() {
      141                     try {
      142                         r.run();
      143                         pendingRunnables.decrementAndGet();
      144                         checkIdle();
      145                     } catch (Throwable t) {
      146                         System.err.println("Exception in runnable");
      147                         t.printStackTrace();
      148                     }
      149                 }
      150             });
      151         }
      152     }
    
    0 讨论(0)
  • 2020-12-03 18:24

    Setting the EventDispatcher to the root Node worked for me.

     public class Frame extends Pane {
        Frame() {
            setEventDispatcher(new EventDispatcher() {
    
                @Override
                public Event dispatchEvent(Event event, EventDispatchChain chain) {
                    try {
                        return chain.dispatchEvent(event);
                    } catch (final Exception e) {
                        // handle all the exceptions here 
                        return null;
                    }
                }
            });
        }
    }
    
    0 讨论(0)
  • 2020-12-03 18:29

    Some managed threads such as the UI Event Handler and ExecutorServices capture Throwable themselves to avoid the threads dying. Only threads which die will use this UncaughtExceptionHandler. If you want to capture exception thrown you have to do thsi in the method which can throw these exceptions.

    If the UI Event Handler has a way of reporting exceptions it will be a different method.

    Your second example will catch exception thrown in that thread. Exception thrown on other threads will be catch on that thread.

    0 讨论(0)
提交回复
热议问题