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}