google/guava · error · RuntimeException
failure during tearDown
Error message
failure during tearDown
What it means
TearDownStack.runTearDown() runs each registered TearDown in LIFO order. If a callback throws a checked exception, it is wrapped in a RuntimeException("failure during tearDown", cause) because TearDown.tearDown() declares no checked exceptions. Unchecked throwables are rethrown as-is; later failures are attached via addSuppressed.
Source
Thrown at android/guava-testlib/src/com/google/common/testing/TearDownStack.java:105
}
for (TearDown tearDown : stackCopy) {
try {
tearDown.tearDown();
} catch (Throwable t) {
if (suppressThrows) {
logger.log(Level.INFO, "exception thrown during tearDown", t);
} else {
if (exception == null) {
exception = t;
} else {
exception.addSuppressed(t);
}
}
}
}
if (exception != null) {
throwIfUnchecked(exception);
throw new RuntimeException("failure during tearDown", exception);
}
}
}
View on GitHub (pinned to 94f39958ba)
Solutions
- Catch checked exceptions inside tearDown() and handle/log them so they never escape the callback.
- Re-throw as an unchecked exception (e.g. RuntimeException) from within tearDown() if the failure must surface — unchecked throwables propagate without wrapping.
- Construct the stack with suppressThrows=true if you want failures logged (Level.INFO) instead of thrown.
- Prefer try-with-resources / AutoCloseable outside the stack for resources with checked-exception close().
Example fix
// before
stack.addTearDown(() -> {
socket.close(); // throws IOException -> wrapped RuntimeException
});
// after
stack.addTearDown(() -> {
try { socket.close(); }
catch (IOException e) { throw new RuntimeException(e); }
}); Defensive patterns
Strategy: try-catch
Validate before calling
// Keep checked exceptions inside tearDown; never let them escape the callback.
stack.addTearDown(() -> {
try { resource.close(); }
catch (IOException e) { /* log or rethrow unchecked */ }
}); Try / catch
// runTearDown wraps checked exceptions as RuntimeException; if you must drive
// it, unwrap the cause to inspect the original failure.
try {
stack.runTearDown();
} catch (RuntimeException e) {
Throwable c = e.getCause(); // the real checked exception
...
} Prevention
- Catch all checked exceptions inside each TearDown.tearDown() body.
- Re-throw unchecked exceptions if the failure must propagate.
- Use suppressThrows=true when you want failures logged rather than thrown.
- Prefer try-with-resources for resources whose close() throws checked exceptions.
When it happens
Trigger: A TearDown.tearDown() implementation throws a checked exception (e.g. IOException from closing a stream, SQLException). The wrapper is thrown at the end of runTearDown() after all callbacks have been attempted.
Common situations: Cleanup callbacks performing I/O, JDBC, or network teardown that can fail; using TearDownStack where callbacks were written without internal try-catch.
Related errors
- %s returns null and cannot be used to test instance methods.
- at index %s
- wrong exception thrown from %s when passing null to %s param
- $ITEM must not be $RELATIONSHIP to $OTHER
- Unexpected interrupt while waiting for future
AI-assisted analysis of google/guava@94f39958ba (2026-08-13).
Data as JSON: /api/errors/f9c3372dfccb1ab4.
Report an issue: GitHub.