@@ -433,18 +433,51 @@ INFO: Method [sleep50ms] took 53 ms.
433433[[extensions-exception-handling]]
434434=== Exception Handling
435435
436- `{TestExecutionExceptionHandler}` defines the API for `Extensions` that wish to handle
437- exceptions thrown during test execution.
436+ Exceptions thrown during the test execution may be intercepted and handled accordingly
437+ before propagating further, so that certain actions like error logging or resource releasing
438+ may be defined in specialized `Extensions`. JUnit Jupiter offers API for `Extensions` that
439+ wish to handle exceptions thrown during `@Test` methods via `{TestExecutionExceptionHandler}`
440+ and for those thrown during one of test lifecycle methods (`@BeforeAll`, `@BeforeEach`,
441+ `@AfterEach` and `@AfterAll`) via `{LifecycleMethodExecutionExceptionHandler}`
438442
439443The following example shows an extension which will swallow all instances of `IOException`
440444but rethrow any other type of exception.
441445
442446[source,java,indent=0]
443- .An exception handling extension
447+ .An exception handling extension that filters IOExceptions in test execution
444448----
445449include::{testDir}/example/exception/IgnoreIOExceptionExtension.java[tags=user_guide]
446450----
447451
452+ Another example shows how to record the state of an application under test exactly at
453+ the point of unexpected exception being thrown during setup and cleanup. Note that unlike
454+ relying on lifecycle callbacks, which may or may not be executed depending on the test
455+ status, this solution guarantees execution immediately after failing `@BeforeAll`,
456+ `@BeforeEach`, `@AfterEach` or `@AfterAll`.
457+
458+ [source,java,indent=0]
459+ .An exception handling extension that records application state on error
460+ ----
461+ include::{testDir}/example/exception/RecordStateOnErrorExtension.java[tags=user_guide]
462+ ----
463+
464+ Multiple execution exception handlers may be invoked for the same lifecycle method in
465+ order of declaration. If one of the handlers swallows the handled exception, subsequent
466+ ones will not be executed, and no failure will be propagated to JUnit engine, as if the
467+ exception was never thrown. Handlers may also choose to rethrow the exception or throw
468+ a different one, potentially wrapping the original.
469+
470+ Extensions implementing `{LifecycleMethodExecutionExceptionHandler}` that wish to handle
471+ exceptions thrown during `@BeforeAll` or `@AfterAll` need to be registered on a class level,
472+ while handlers for `BeforeEach` and `AfterEach` may be also registered for individual
473+ test methods.
474+
475+ [source,java,indent=0]
476+ .An exception handling extension that records application state on error
477+ ----
478+ include::{testDir}/example/exception/MultipleHandlersTestCase.java[tags=user_guide]
479+ ----
480+
448481[[extensions-intercepting-invocations]]
449482=== Intercepting Invocations
450483
@@ -584,7 +617,7 @@ test method and will be repeated for every test method in the test class.
584617[#extensions-execution-order-diagram,reftext='{figure-caption}']
585618image::extensions_lifecycle.png[caption='',title='{figure-caption}']
586619
587- The following table further explains the twelve steps in the
620+ The following table further explains the sixteen steps in the
588621<<extensions-execution-order-diagram>> diagram.
589622
590623[cols="5,15,80"]
@@ -600,42 +633,58 @@ The following table further explains the twelve steps in the
600633| user code executed before all tests of the container are executed
601634
602635| 3
636+ | interface `org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler`
637+ | extension code for handling exceptions thrown during a method annotated with `@BeforeAll`
638+
639+ | 4
603640| interface `org.junit.jupiter.api.extension.BeforeEachCallback`
604641| extension code executed before each test is executed
605642
606- | 4
643+ | 5
607644| annotation `org.junit.jupiter.api.BeforeEach`
608645| user code executed before each test is executed
609646
610- | 5
647+ | 6
648+ | interface `org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler`
649+ | extension code for handling exceptions thrown during a method annotated with `@BeforeEach`
650+
651+ | 7
611652| interface `org.junit.jupiter.api.extension.BeforeTestExecutionCallback`
612653| extension code executed immediately before a test is executed
613654
614- | 6
655+ | 8
615656| annotation `org.junit.jupiter.api.Test`
616657| user code of the actual test method
617658
618- | 7
659+ | 9
619660| interface `org.junit.jupiter.api.extension.TestExecutionExceptionHandler`
620661| extension code for handling exceptions thrown during a test
621662
622- | 8
663+ | 10
623664| interface `org.junit.jupiter.api.extension.AfterTestExecutionCallback`
624665| extension code executed immediately after test execution and its corresponding exception handlers
625666
626- | 9
667+ | 11
627668| annotation `org.junit.jupiter.api.AfterEach`
628669| user code executed after each test is executed
629670
630- | 10
671+ | 12
672+ | interface `org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler`
673+ | extension code for handling exceptions thrown during a method annotated with `@AfterEach`
674+
675+ | 13
631676| interface `org.junit.jupiter.api.extension.AfterEachCallback`
632677| extension code executed after each test is executed
633678
634- | 11
679+ | 14
635680| annotation `org.junit.jupiter.api.AfterAll`
636681| user code executed after all tests of the container are executed
637682
638- | 12
683+ | 15
684+ | interface `org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler`
685+ | extension code for handling exceptions thrown during a method annotated with `@AfterAll`
686+
687+ | 16
639688| interface `org.junit.jupiter.api.extension.AfterAllCallback`
640689| extension code executed after all tests of the container are executed
641690
0 commit comments