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 }