[[dynamic-command-exitcode-annotation]]
= @ExceptionResolver

ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]

`@ShellComponent` classes can have `@ExceptionResolver` methods to handle exceptions from component
methods. These are meant for annotated methods.

The exception may match against a top-level exception being propagated (e.g. a direct `IOException`
being thrown) or against a nested cause within a wrapper exception (e.g. an `IOException` wrapped
inside an `IllegalStateException`). This can match at arbitrary cause levels.

For matching exception types, preferably declare the target exception as a method argument, as
the preceding example(s) shows. When multiple exception methods match, a root exception match is
generally preferred to a cause exception match. More specifically, the `ExceptionDepthComparator`
is used to sort exceptions based on their depth from the thrown exception type.

Alternatively, the annotation declaration may narrow the exception types to match, as the
following example shows:

[source, java, indent=0]
----
include::{snippets}/ErrorHandlingSnippets.java[tag=exception-resolver-with-type-in-annotation]
----

[source, java, indent=0]
----
include::{snippets}/ErrorHandlingSnippets.java[tag=exception-resolver-with-type-in-method]
----

`@ExceptionResolver` can also return `String` which is used as an output to console. You can
use `@ExitCode` annotation to define return code.

[source, java, indent=0]
----
include::{snippets}/ErrorHandlingSnippets.java[tag=exception-resolver-with-exitcode-annotation]
----

`@ExceptionResolver` with `void` return type is automatically handled as handled exception.
You can then also define `@ExitCode` and use `Terminal` if you need to write something
into the console:

[source, java, indent=0]
----
include::{snippets}/ErrorHandlingSnippets.java[tag=exception-resolver-with-void]
----

[[method-arguments]]
== Method Arguments
`@ExceptionResolver` methods support the following arguments:

[Attributes]
|===
|Method argument |Description

|Exception type
|For access to the raised exception. This is any type of `Exception` or `Throwable`.

|Terminal
|For access to underlying `JLine` terminal to i.e. get its terminal writer.

|===

[[return-values]]
== Return Values
`@ExceptionResolver` methods support the following return values:

[Attributes]
|===
|Return value |Description

|String
|Plain text to return to a shell. Exit code 1 is used in this case.

|CommandHandlingResult
|Plain `CommandHandlingResult` having message and exit code.

|void
|A method with a void return type is considered to have fully handled the exception. Usually
you would define `Terminal` as a method argument and write response using _terminal writer_
from it. As exception is fully handled, Exit code 0 is used in this case.
|===
