001package org.junit.runners.model; 002 003import java.io.PrintStream; 004import java.io.PrintWriter; 005import java.util.ArrayList; 006import java.util.Collections; 007import java.util.List; 008 009import org.junit.TestCouldNotBeSkippedException; 010import org.junit.internal.AssumptionViolatedException; 011import org.junit.internal.Throwables; 012 013/** 014 * Collects multiple {@code Throwable}s into one exception. 015 * 016 * @since 4.9 017 */ 018public class MultipleFailureException extends Exception { 019 private static final long serialVersionUID = 1L; 020 021 /* 022 * We have to use the f prefix until the next major release to ensure 023 * serialization compatibility. 024 * See https://github.com/junit-team/junit4/issues/976 025 */ 026 private final List<Throwable> fErrors; 027 028 public MultipleFailureException(List<Throwable> errors) { 029 if (errors.isEmpty()) { 030 throw new IllegalArgumentException( 031 "List of Throwables must not be empty"); 032 } 033 this.fErrors = new ArrayList<Throwable>(errors.size()); 034 for (Throwable error : errors) { 035 if (error instanceof AssumptionViolatedException) { 036 error = new TestCouldNotBeSkippedException((AssumptionViolatedException) error); 037 } 038 fErrors.add(error); 039 } 040 } 041 042 public List<Throwable> getFailures() { 043 return Collections.unmodifiableList(fErrors); 044 } 045 046 @Override 047 public String getMessage() { 048 StringBuilder sb = new StringBuilder( 049 String.format("There were %d errors:", fErrors.size())); 050 for (Throwable e : fErrors) { 051 sb.append(String.format("%n %s(%s)", e.getClass().getName(), e.getMessage())); 052 } 053 return sb.toString(); 054 } 055 056 @Override 057 public void printStackTrace() { 058 for (Throwable e: fErrors) { 059 e.printStackTrace(); 060 } 061 } 062 063 @Override 064 public void printStackTrace(PrintStream s) { 065 for (Throwable e: fErrors) { 066 e.printStackTrace(s); 067 } 068 } 069 070 @Override 071 public void printStackTrace(PrintWriter s) { 072 for (Throwable e: fErrors) { 073 e.printStackTrace(s); 074 } 075 } 076 077 /** 078 * Asserts that a list of throwables is empty. If it isn't empty, 079 * will throw {@link MultipleFailureException} (if there are 080 * multiple throwables in the list) or the first element in the list 081 * (if there is only one element). 082 * 083 * @param errors list to check 084 * @throws Exception or Error if the list is not empty 085 */ 086 @SuppressWarnings("deprecation") 087 public static void assertEmpty(List<Throwable> errors) throws Exception { 088 if (errors.isEmpty()) { 089 return; 090 } 091 if (errors.size() == 1) { 092 throw Throwables.rethrowAsException(errors.get(0)); 093 } 094 095 /* 096 * Many places in the code are documented to throw 097 * org.junit.internal.runners.model.MultipleFailureException. 098 * That class now extends this one, so we throw the internal 099 * exception in case developers have tests that catch 100 * MultipleFailureException. 101 */ 102 throw new org.junit.internal.runners.model.MultipleFailureException(errors); 103 } 104}