AppError class.

Java To Go!
To Check or Not to Check?
Todd Lauinger
Listing 1. AppError class.


  package log;

import java.io.*;

/**
 * The <code>AppError</code> class is a
 * base class for exceptions that need
 * to be "bubbled" up to a common error
 * handling "catch" block.  It is
 * particularly useful when catching
 * checked exceptions that need to be
 * bubbled up, as the <code>AppError</code>
 * class can be used to "wrap" the
 * original exception and provide a user
 * friendly message for display.  It is a
 * subclass of <code>RuntimeException</code>
 * so there is no need to immediately
 * handle it with a try-catch block,
 * thereby helping to streamline your
 * code and consolidate error handling
 * redundancies into common error
 * handling routines.<p>
 *
 * This class also supports automatic
 * logging of the error, with a stack trace,
 * to the JLog log of your choice.
 *
 * @author Todd Lauinger
 * @version $Revision: 1.2 $
 */
public class AppError 
    extends RuntimeException
{
	/**
	 * Holds a reference to the original
	 * Error or Exception object.
	 */
	protected Throwable originalThrownObject;

  /**
    * Empty constructor to create a
	 * <code>AppError</code> with no
	 * message.
	 */
	public AppError()
	{
		super();
	}

	/**
	 * Constructor accepting a reference
	 * to a Throwable object. This is
	 * normally used when using the
	 * <code>AppError</code> to "wrap"
	 * a caught exception.
	 */
	public AppError(Throwable t)
	{
		super();
		originalThrownObject = t;
	}

	/**
	 * Constructor accepting a
	 * message string.  Since no
	 * exception is "wrapped",
	 * no stack trace can be printed.
	 */
	public AppError(String s)
	{
		super(s);
	}

	/**
	 * Constructor accepting a
	 * message and a Throwable object.
	 * This is normally used when
	 * using the <code>AppError</code>
	 * to "wrap" a caught exception.
	 */
	public AppError(String s, Throwable t)
	{
		super(s);
		originalThrownObject = t;
	}

	/**
	 * Constructor accepting a message,
	 * a Throwable object, and logging
	 * information. Use this message
	 * to automatically construct the
	 * exception, generate message text
	 * and a stack trace, and log it
	 * all to the log and logging level
	 * given as input.
	 */
	public AppError(String s, Throwable t,
	    Log log, int loggingLevel)
	{
		this(s, t);
		log.logString(this.toString(), loggingLevel);
	}

    /**

   * Takes the <code>Throwable</code>

	* given as input, generates a stack
     * trace, and converts it to a string
     * to be returned.
     */
    public static String
        getStackTraceAsString(Throwable e)
    {
        // Create a buffer to place the
        // stack trace, giving an initial
        // buffer size of 1000 bytes so
        // it doesn't grow as frequently
        ByteArrayOutputStream outputStream =
            new ByteArrayOutputStream(1000);
        // Create a print writer on that
        // output buffer without autoflush
        // for better performance
        PrintWriter printWriter =
            new PrintWriter(outputStream);
        // Write the stack trace to the
        // stream and manually flush
        e.printStackTrace(printWriter);
        printWriter.flush();

     // Convert and return as a string
     return outputStream.toString();
}

	/**
	 * Returns the original thrown object.
	 * The <code>AppError</code> is "wrapping" it.
	 */
	public Throwable getOriginalThrownObject()
	{
		return originalThrownObject;
	}

	/**
	 * Returns a String representing
	 * the <code>AppError</code> information.
	 */
	public String toString()
	{
		StringBuffer sb =
		    new StringBuffer().append("Application Error: \n");

		if (getMessage() != null)
		{
			sb.append("Message: ");
			sb.append(getMessage());
			sb.append("\n");
		}
		if (originalThrownObject != null)
		{
			sb.append("Original thrown object message: ");
			sb.append(originalThrownObject.toString());
			sb.append("\n");
			sb.append("Stack trace:");
	sb.append(getStackTraceAsString(
	                  originalThrownObject));
		}
		return sb.toString();
        }
    }