Skip to content

Commit 0adc492

Browse files
committed
TestContextManager consistently handles Errors from listener invocations
Issue: SPR-13961
1 parent 08eb623 commit 0adc492

File tree

1 file changed

+38
-27
lines changed

1 file changed

+38
-27
lines changed

spring-test/src/main/java/org/springframework/test/context/TestContextManager.java

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
2525
import org.apache.commons.logging.LogFactory;
2626

2727
import org.springframework.util.Assert;
28+
import org.springframework.util.ReflectionUtils;
2829

2930
/**
3031
* {@code TestContextManager} is the main entry point into the <em>Spring
@@ -194,10 +195,12 @@ public void beforeTestClass() throws Exception {
194195
try {
195196
testExecutionListener.beforeTestClass(getTestContext());
196197
}
197-
catch (Exception ex) {
198-
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
199-
"] to process 'before class' callback for test class [" + testClass + "]", ex);
200-
throw ex;
198+
catch (Throwable ex) {
199+
if (logger.isWarnEnabled()) {
200+
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
201+
"] to process 'before class' callback for test class [" + testClass + "]", ex);
202+
}
203+
ReflectionUtils.rethrowException(ex);
201204
}
202205
}
203206
}
@@ -227,10 +230,12 @@ public void prepareTestInstance(Object testInstance) throws Exception {
227230
try {
228231
testExecutionListener.prepareTestInstance(getTestContext());
229232
}
230-
catch (Exception ex) {
231-
logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
232-
"] to prepare test instance [" + testInstance + "]", ex);
233-
throw ex;
233+
catch (Throwable ex) {
234+
if (logger.isErrorEnabled()) {
235+
logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
236+
"] to prepare test instance [" + testInstance + "]", ex);
237+
}
238+
ReflectionUtils.rethrowException(ex);
234239
}
235240
}
236241
}
@@ -264,11 +269,13 @@ public void beforeTestMethod(Object testInstance, Method testMethod) throws Exce
264269
try {
265270
testExecutionListener.beforeTestMethod(getTestContext());
266271
}
267-
catch (Exception ex) {
268-
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
269-
"] to process 'before' execution of test method [" + testMethod + "] for test instance [" +
270-
testInstance + "]", ex);
271-
throw ex;
272+
catch (Throwable ex) {
273+
if (logger.isWarnEnabled()) {
274+
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
275+
"] to process 'before' execution of test method [" + testMethod + "] for test instance [" +
276+
testInstance + "]", ex);
277+
}
278+
ReflectionUtils.rethrowException(ex);
272279
}
273280
}
274281
}
@@ -305,24 +312,26 @@ public void afterTestMethod(Object testInstance, Method testMethod, Throwable ex
305312
}
306313
getTestContext().updateState(testInstance, testMethod, exception);
307314

308-
Exception afterTestMethodException = null;
315+
Throwable afterTestMethodException = null;
309316
// Traverse the TestExecutionListeners in reverse order to ensure proper
310317
// "wrapper"-style execution of listeners.
311318
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
312319
try {
313320
testExecutionListener.afterTestMethod(getTestContext());
314321
}
315-
catch (Exception ex) {
316-
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
317-
"] to process 'after' execution for test: method [" + testMethod + "], instance [" +
318-
testInstance + "], exception [" + exception + "]", ex);
322+
catch (Throwable ex) {
323+
if (logger.isWarnEnabled()) {
324+
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
325+
"] to process 'after' execution for test: method [" + testMethod + "], instance [" +
326+
testInstance + "], exception [" + exception + "]", ex);
327+
}
319328
if (afterTestMethodException == null) {
320329
afterTestMethodException = ex;
321330
}
322331
}
323332
}
324333
if (afterTestMethodException != null) {
325-
throw afterTestMethodException;
334+
ReflectionUtils.rethrowException(afterTestMethodException);
326335
}
327336
}
328337

@@ -347,23 +356,25 @@ public void afterTestClass() throws Exception {
347356
}
348357
getTestContext().updateState(null, null, null);
349358

350-
Exception afterTestClassException = null;
359+
Throwable afterTestClassException = null;
351360
// Traverse the TestExecutionListeners in reverse order to ensure proper
352361
// "wrapper"-style execution of listeners.
353362
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
354363
try {
355364
testExecutionListener.afterTestClass(getTestContext());
356365
}
357-
catch (Exception ex) {
358-
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
359-
"] to process 'after class' callback for test class [" + testClass + "]", ex);
360-
if (afterTestClassException == null) {
361-
afterTestClassException = ex;
366+
catch (Throwable ex) {
367+
if (logger.isWarnEnabled()) {
368+
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener +
369+
"] to process 'after class' callback for test class [" + testClass + "]", ex);
370+
if (afterTestClassException == null) {
371+
afterTestClassException = ex;
372+
}
362373
}
363374
}
364375
}
365376
if (afterTestClassException != null) {
366-
throw afterTestClassException;
377+
ReflectionUtils.rethrowException(afterTestClassException);
367378
}
368379
}
369380

0 commit comments

Comments
 (0)