    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.lang.exception;
    018
    019    import java.io.PrintStream;
    020    import java.io.PrintWriter;
    021
    022    /**
    023     * The base class of all exceptions which can contain other exceptions.
    024     *
    025     * It is intended to ease the debugging by carrying on the information
    026     * about the exception which was caught and provoked throwing the
    027     * current exception. Catching and rethrowing may occur multiple
    028     * times, and provided that all exceptions except the first one
    029     * are descendants of <code>NestedException</code>, when the
    030     * exception is finally printed out using any of the <code>
    031     * printStackTrace()</code> methods, the stack trace will contain
    032     * the information about all exceptions thrown and caught on
    033     * the way.
    034     * <p> Running the following program
    035     * <p><blockquote><pre>
    036     *  1 import org.apache.commons.lang.exception.NestableException;
    037     *  2
    038     *  3 public class Test {
    039     *  4     public static void main( String[] args ) {
    040     *  5         try {
    041     *  6             a();
    042     *  7         } catch(Exception e) {
    043     *  8             e.printStackTrace();
    044     *  9         }
    045     * 10      }
    046     * 11
    047     * 12      public static void a() throws Exception {
    048     * 13          try {
    049     * 14              b();
    050     * 15          } catch(Exception e) {
    051     * 16              throw new NestableException("foo", e);
    052     * 17          }
    053     * 18      }
    054     * 19
    055     * 20      public static void b() throws Exception {
    056     * 21          try {
    057     * 22              c();
    058     * 23          } catch(Exception e) {
    059     * 24              throw new NestableException("bar", e);
    060     * 25          }
    061     * 26      }
    062     * 27
    063     * 28      public static void c() throws Exception {
    064     * 29          throw new Exception("baz");
    065     * 30      }
    066     * 31 }
    067     * </pre></blockquote>
    068     * <p>Yields the following stack trace:
    069     * <p><blockquote><pre>
    070     * org.apache.commons.lang.exception.NestableException: foo
    071     *         at Test.a(Test.java:16)
    072     *         at Test.main(Test.java:6)
    073     * Caused by: org.apache.commons.lang.exception.NestableException: bar
    074     *         at Test.b(Test.java:24)
    075     *         at Test.a(Test.java:14)
    076     *         ... 1 more
    077     * Caused by: java.lang.Exception: baz
    078     *         at Test.c(Test.java:29)
    079     *         at Test.b(Test.java:22)
    080     *         ... 2 more
    081     * </pre></blockquote><br>
    082     *
    083     * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
    084     * @author Daniel L. Rall
    085     * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
    086     * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
    087     * @since 1.0
    088     * @version $Id: NestableException.java 512889 2007-02-28 18:18:20Z dlr $
    089     */
    090    public class NestableException extends Exception implements Nestable {
    091
    092        /**
    093         * Required for serialization support.
    094         *
    095         * @see java.io.Serializable
    096         */
    097        private static final long serialVersionUID = 1L;
    098
    099        /**
    100         * The helper instance which contains much of the code which we
    101         * delegate to.
    102         */
    103        protected NestableDelegate delegate = new NestableDelegate(this);
    104
    105        /**
    106         * Holds the reference to the exception or error that caused
    107         * this exception to be thrown.
    108         */
    109        private Throwable cause = null;
    110
    111        /**
    112         * Constructs a new <code>NestableException</code> without specified
    113         * detail message.
    114         */
    115        public NestableException() {
    116            super();
    117        }
    118
    119        /**
    120         * Constructs a new <code>NestableException</code> with specified
    121         * detail message.
    122         *
    123         * @param msg The error message.
    124         */
    125        public NestableException(String msg) {
    126            super(msg);
    127        }
    128
    129        /**
    130         * Constructs a new <code>NestableException</code> with specified
    131         * nested <code>Throwable</code>.
    132         *
    133         * @param cause the exception or error that caused this exception to be
    134         * thrown
    135         */
    136        public NestableException(Throwable cause) {
    137            super();
    138            this.cause = cause;
    139        }
    140
    141        /**
    142         * Constructs a new <code>NestableException</code> with specified
    143         * detail message and nested <code>Throwable</code>.
    144         *
    145         * @param msg    the error message
    146         * @param cause  the exception or error that caused this exception to be
    147         * thrown
    148         */
    149        public NestableException(String msg, Throwable cause) {
    150            super(msg);
    151            this.cause = cause;
    152        }
    153
    154        /**
    155         * {@inheritDoc}
    156         */
    157        public Throwable getCause() {
    158            return cause;
    159        }
    160
    161        /**
    162         * Returns the detail message string of this throwable. If it was
    163         * created with a null message, returns the following:
    164         * (cause==null ? null : cause.toString()).
    165         *
    166         * @return String message string of the throwable
    167         */
    168        public String getMessage() {
    169            if (super.getMessage() != null) {
    170                return super.getMessage();
    171            } else if (cause != null) {
    172                return cause.toString();
    173            } else {
    174                return null;
    175            }
    176        }
    177
    178        /**
    179         * {@inheritDoc}
    180         */
    181        public String getMessage(int index) {
    182            if (index == 0) {
    183                return super.getMessage();
    184            }
    185            return delegate.getMessage(index);
    186        }
    187
    188        /**
    189         * {@inheritDoc}
    190         */
    191        public String[] getMessages() {
    192            return delegate.getMessages();
    193        }
    194
    195        /**
    196         * {@inheritDoc}
    197         */
    198        public Throwable getThrowable(int index) {
    199            return delegate.getThrowable(index);
    200        }
    201
    202        /**
    203         * {@inheritDoc}
    204         */
    205        public int getThrowableCount() {
    206            return delegate.getThrowableCount();
    207        }
    208
    209        /**
    210         * {@inheritDoc}
    211         */
    212        public Throwable[] getThrowables() {
    213            return delegate.getThrowables();
    214        }
    215
    216        /**
    217         * {@inheritDoc}
    218         */
    219        public int indexOfThrowable(Class type) {
    220            return delegate.indexOfThrowable(type, 0);
    221        }
    222
    223        /**
    224         * {@inheritDoc}
    225         */
    226        public int indexOfThrowable(Class type, int fromIndex) {
    227            return delegate.indexOfThrowable(type, fromIndex);
    228        }
    229
    230        /**
    231         * {@inheritDoc}
    232         */
    233        public void printStackTrace() {
    234            delegate.printStackTrace();
    235        }
    236
    237        /**
    238         * {@inheritDoc}
    239         */
    240        public void printStackTrace(PrintStream out) {
    241            delegate.printStackTrace(out);
    242        }
    243
    244        /**
    245         * {@inheritDoc}
    246         */
    247        public void printStackTrace(PrintWriter out) {
    248            delegate.printStackTrace(out);
    249        }
    250
    251        /**
    252         * {@inheritDoc}
    253         */
    254        public final void printPartialStackTrace(PrintWriter out) {
    255            super.printStackTrace(out);
    256        }
    257
    258    }