
package uk.co.wingpath.util;

/**
* This class implements {@link java.lang.Thread.UncaughtExceptionHandler}
* by printing a stack trace and then calling {@link System#exit System.exit}.
*/
public class UncaughtExceptionHandler
    implements Thread.UncaughtExceptionHandler
{
    private Reporter reporter;

    /**
    * Constructs an {@code UncaughtExceptionHandler} using the specified
    * reporter.
    * <p>If the reporter is not {@code null}, uncaught exceptions are
    * reported using {@link Reporter#fatal(String,Throwable)}.
    * <p>If the reporter is {@code null}, uncaught exceptions are reported
    * to {@code System.err}.
    * <p>After reporting the exception, {@link System#exit} is called.
    * <p>Do not use this handler as the default exception handler (i.e. do
    * not pass it to {@link Thread#setDefaultUncaughtExceptionHandler}), as it
    * would then be used for shutdown-hook threads, and if you call
    * {@code System.exit} from a shutdown hook the whole shutdown freezes
    * (needing a SIGKILL to end the process).
    * @param reporter where to report exceptions. May be {@code null} to
    * report to {@code System.err}.
    */
    public UncaughtExceptionHandler (Reporter reporter)
    {
        this.reporter = reporter;
    }

    public void uncaughtException (Thread t, Throwable e)
    {
        if (reporter != null)
        {
            reporter.fatal ("Uncaught exception in thread '" +
                t.getName () + "'", e);
        }
        else
        {
            System.err.println ("Uncaught exception in thread '" +
                t.getName () + "'");
            e.printStackTrace ();
        }
        System.exit (1);
    }
}

