481 * static void d() throws LowLevelException { 482 * e(); 483 * } 484 * static void e() throws LowLevelException { 485 * throw new LowLevelException(); 486 * } 487 * } 488 * 489 * class HighLevelException extends Exception { 490 * HighLevelException(Throwable cause) { super(cause); } 491 * } 492 * 493 * class MidLevelException extends Exception { 494 * MidLevelException(Throwable cause) { super(cause); } 495 * } 496 * 497 * class LowLevelException extends Exception { 498 * } 499 * </pre> 500 * As of release 7, the platform supports the notion of 501 * <i>suppressed exceptions</i> (in conjunction with automatic 502 * resource management blocks). Any exceptions that were 503 * suppressed in order to deliver an exception are printed out 504 * beneath the stack trace. The format of this information 505 * depends on the implementation, but the following example may be 506 * regarded as typical: 507 * 508 * <pre> 509 * Exception in thread "main" java.lang.Exception: Something happened 510 * at Foo.bar(Foo.java:10) 511 * at Foo.main(Foo.java:5) 512 * Suppressed: Resource$CloseFailException: Resource ID = 0 513 * at Resource.close(Resource.java:26) 514 * at Foo.bar(Foo.java:9) 515 * ... 1 more 516 * </pre> 517 * Note that the "... n more" notation is used on suppressed exceptions 518 * just at it is used on causes. Unlike causes, suppressed exceptions are 519 * indented beyond their "containing exceptions." 520 * 521 * <p>An exception can have both a cause and one or more suppressed 522 * exceptions: 788 !suppressedExceptions.isEmpty()) { // Copy Throwables to new list 789 suppressed = new ArrayList<Throwable>(); 790 for (Throwable t : suppressedExceptions) { 791 if (t == null) 792 throw new NullPointerException(NULL_CAUSE_MESSAGE); 793 suppressed.add(t); 794 } 795 } 796 suppressedExceptions = suppressed; 797 } 798 799 private synchronized void writeObject(ObjectOutputStream s) 800 throws IOException 801 { 802 getOurStackTrace(); // Ensure that stackTrace field is initialized. 803 s.defaultWriteObject(); 804 } 805 806 /** 807 * Adds the specified exception to the list of exceptions that 808 * were suppressed, typically by the automatic resource management 809 * statement, in order to deliver this exception. 810 * 811 * <p>Note that when one exception {@linkplain 812 * #initCause(Throwable) causes} another exception, the first 813 * exception is usually caught and then the second exception is 814 * thrown in response. In contrast, when one exception suppresses 815 * another, two exceptions are thrown in sibling code blocks, such 816 * as in a {@code try} block and in its {@code finally} block, and 817 * control flow can only continue with one exception so the second 818 * is recorded as a suppressed exception of the first. 819 * 820 * @param exception the exception to be added to the list of 821 * suppressed exceptions 822 * @throws NullPointerException if {@code exception} is null 823 * @throws IllegalArgumentException if {@code exception} is this 824 * throwable; a throwable cannot suppress itself. 825 * @since 1.7 826 */ 827 public synchronized void addSuppressedException(Throwable exception) { 828 if (exception == null) 829 throw new NullPointerException(NULL_CAUSE_MESSAGE); 830 if (exception == this) 831 throw new IllegalArgumentException("Self-suppression not permitted"); 832 833 if (suppressedExceptions == null) 834 suppressedExceptions = new ArrayList<Throwable>(); 835 suppressedExceptions.add(exception); 836 } 837 838 private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0]; 839 840 /** 841 * Returns an array containing all of the exceptions that were 842 * suppressed, typically by the automatic resource management 843 * statement, in order to deliver this exception. 844 * 845 * @return an array containing all of the exceptions that were 846 * suppressed to deliver this exception. 847 * @since 1.7 848 */ 849 public synchronized Throwable[] getSuppressedExceptions() { 850 if (suppressedExceptions == null) 851 return EMPTY_THROWABLE_ARRAY; 852 else 853 return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY); 854 } 855 } | 481 * static void d() throws LowLevelException { 482 * e(); 483 * } 484 * static void e() throws LowLevelException { 485 * throw new LowLevelException(); 486 * } 487 * } 488 * 489 * class HighLevelException extends Exception { 490 * HighLevelException(Throwable cause) { super(cause); } 491 * } 492 * 493 * class MidLevelException extends Exception { 494 * MidLevelException(Throwable cause) { super(cause); } 495 * } 496 * 497 * class LowLevelException extends Exception { 498 * } 499 * </pre> 500 * As of release 7, the platform supports the notion of 501 * <i>suppressed exceptions</i> (in conjunction with the {@code 502 * try}-with-resources statement). Any exceptions that were 503 * suppressed in order to deliver an exception are printed out 504 * beneath the stack trace. The format of this information 505 * depends on the implementation, but the following example may be 506 * regarded as typical: 507 * 508 * <pre> 509 * Exception in thread "main" java.lang.Exception: Something happened 510 * at Foo.bar(Foo.java:10) 511 * at Foo.main(Foo.java:5) 512 * Suppressed: Resource$CloseFailException: Resource ID = 0 513 * at Resource.close(Resource.java:26) 514 * at Foo.bar(Foo.java:9) 515 * ... 1 more 516 * </pre> 517 * Note that the "... n more" notation is used on suppressed exceptions 518 * just at it is used on causes. Unlike causes, suppressed exceptions are 519 * indented beyond their "containing exceptions." 520 * 521 * <p>An exception can have both a cause and one or more suppressed 522 * exceptions: 788 !suppressedExceptions.isEmpty()) { // Copy Throwables to new list 789 suppressed = new ArrayList<Throwable>(); 790 for (Throwable t : suppressedExceptions) { 791 if (t == null) 792 throw new NullPointerException(NULL_CAUSE_MESSAGE); 793 suppressed.add(t); 794 } 795 } 796 suppressedExceptions = suppressed; 797 } 798 799 private synchronized void writeObject(ObjectOutputStream s) 800 throws IOException 801 { 802 getOurStackTrace(); // Ensure that stackTrace field is initialized. 803 s.defaultWriteObject(); 804 } 805 806 /** 807 * Adds the specified exception to the list of exceptions that 808 * were suppressed, typically by the {@code try}-with-resources 809 * statement, in order to deliver this exception. 810 * 811 * <p>Note that when one exception {@linkplain 812 * #initCause(Throwable) causes} another exception, the first 813 * exception is usually caught and then the second exception is 814 * thrown in response. In contrast, when one exception suppresses 815 * another, two exceptions are thrown in sibling code blocks, such 816 * as in a {@code try} block and in its {@code finally} block, and 817 * control flow can only continue with one exception so the second 818 * is recorded as a suppressed exception of the first. 819 * 820 * @param exception the exception to be added to the list of 821 * suppressed exceptions 822 * @throws NullPointerException if {@code exception} is null 823 * @throws IllegalArgumentException if {@code exception} is this 824 * throwable; a throwable cannot suppress itself. 825 * @since 1.7 826 */ 827 public synchronized void addSuppressedException(Throwable exception) { 828 if (exception == null) 829 throw new NullPointerException(NULL_CAUSE_MESSAGE); 830 if (exception == this) 831 throw new IllegalArgumentException("Self-suppression not permitted"); 832 833 if (suppressedExceptions == null) 834 suppressedExceptions = new ArrayList<Throwable>(); 835 suppressedExceptions.add(exception); 836 } 837 838 private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0]; 839 840 /** 841 * Returns an array containing all of the exceptions that were 842 * suppressed, typically by the {@code try}-with-resources 843 * statement, in order to deliver this exception. 844 * 845 * @return an array containing all of the exceptions that were 846 * suppressed to deliver this exception. 847 * @since 1.7 848 */ 849 public synchronized Throwable[] getSuppressedExceptions() { 850 if (suppressedExceptions == null) 851 return EMPTY_THROWABLE_ARRAY; 852 else 853 return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY); 854 } 855 } |