001package jmri.util.exceptionhandler;
002
003import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
004
005import java.awt.GraphicsEnvironment;
006
007import jmri.util.swing.ExceptionContext;
008
009/**
010 * Class to log exceptions that rise to the top of threads, including to the top
011 * of the AWT event processing loop.
012 *
013 * Using code must install this with
014 * <pre>
015 * Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler());
016 * </pre>
017 *
018 * @author Bob Jacobsen Copyright 2003, 2010
019 */
020public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
021
022    @Override
023    public void uncaughtException(Thread t, Throwable e) {
024
025        // see http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadDeath.html
026        if (e instanceof java.lang.ThreadDeath) {
027            log.info("Thread has stopped: {}", t.getName());
028            return;
029        }
030
031        log.error("Uncaught Exception caught by jmri.util.exceptionhandler.UncaughtExceptionHandler", e);
032
033        if (e instanceof Error) {
034            if (!GraphicsEnvironment.isHeadless()) {
035                jmri.util.swing.ExceptionDisplayFrame.displayExceptionDisplayFrame(null,
036                    new ErrorContext(e));
037            }
038            log.error("System Exiting");
039            systemExit();
040        }
041    }
042
043    @SuppressFBWarnings(value="DM_EXIT", justification="Errors should terminate the application")
044    protected void systemExit(){
045        System.exit(126);
046    }
047
048    private static class ErrorContext extends ExceptionContext {
049
050        public ErrorContext(@javax.annotation.Nonnull Throwable ex) {
051            super(ex, "", "");
052            this.prefaceString = Bundle.getMessage("UnrecoverableErrorMessage");
053        }
054
055        @Override
056        public String getTitle() {
057            return Bundle.getMessage("UnrecoverableErrorTitle");
058        }
059
060    }
061
062    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UncaughtExceptionHandler.class);
063
064}