001 package org.junit.runners.model;
002
003 import java.io.PrintStream;
004 import java.io.PrintWriter;
005 import java.util.ArrayList;
006 import java.util.Collections;
007 import java.util.List;
008
009 import org.junit.TestCouldNotBeSkippedException;
010 import org.junit.internal.AssumptionViolatedException;
011 import org.junit.internal.Throwables;
012
013 /**
014 * Collects multiple {@code Throwable}s into one exception.
015 *
016 * @since 4.9
017 */
018 public 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 }