001/*
002 * #%L
003 * Netarchivesuite - common
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023package dk.netarkivet.common.utils;
024
025import java.io.PrintWriter;
026import java.io.StringWriter;
027import java.io.Writer;
028import java.sql.SQLException;
029
030import dk.netarkivet.common.exceptions.ArgumentNotValid;
031
032/**
033 * Utilities for reading a stacktrace.
034 */
035public class ExceptionUtils {
036
037    /**
038     * Utility class, do not instantiate.
039     */
040    private ExceptionUtils() {
041    }
042
043    /**
044     * Prints the stacktrace of an exception to a String. Why this functionality is not included in the standard java
045     * libraries is anybody's guess.
046     *
047     * @param aThrowable An exception
048     * @return String containing a stacktrace of exception aThrowable. Will return the string "null" and a linebreak if
049     * aThrowable is null.
050     */
051    public static String getStackTrace(Throwable aThrowable) {
052        final Writer result = new StringWriter();
053        final PrintWriter printWriter = new PrintWriter(result);
054        if (aThrowable != null) {
055            aThrowable.printStackTrace(printWriter);
056        } else {
057            printWriter.println("null");
058        }
059        return result.toString();
060    }
061
062    /**
063     * SQLExceptions have their own stack of causes accessed via the getNextException() method. This utility provides a
064     * string representation of those causes for use in logging or rethrowing
065     *
066     * @param e the original top-level exception
067     * @return a String describing the exception
068     */
069    public static String getSQLExceptionCause(SQLException e) {
070        ArgumentNotValid.checkNotNull(e, "SQLException");
071        StringBuffer message = new StringBuffer("SQLException trace:\n");
072        do {
073            message.append(getSingleSQLExceptionCause(e));
074            e = e.getNextException();
075            if (e != null) {
076                message.append("NextException:\n");
077            }
078        } while (e != null);
079        message.append("End of SQLException trace");
080        return message.toString();
081    }
082
083    private static StringBuffer getSingleSQLExceptionCause(SQLException e) {
084        StringBuffer message = new StringBuffer();
085        message.append("SQL State:").append(e.getSQLState()).append("\n");
086        message.append("Error Code:").append(e.getErrorCode()).append("\n");
087        StringWriter string_writer = new StringWriter();
088        PrintWriter writer = new PrintWriter(string_writer);
089        e.printStackTrace(writer);
090        message.append(string_writer.getBuffer());
091        return message;
092    }
093
094}