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 }