This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Shell 3.4.0!

Exception Resolving

Unhandled exceptions will bubble up into shell’s ResultHandlerService and then eventually handled by some instance of ResultHandler. Chain of ExceptionResolver implementations can be used to resolve exceptions and gives you the flexibility to return a message to get written into the console together with exit code which are wrapped within CommandHandlingResult. CommandHandlingResult may contain a message and/or exit code.

static class CustomExceptionResolver implements CommandExceptionResolver {

	@Override
	public CommandHandlingResult resolve(Exception e) {
		if (e instanceof CustomException) {
			return CommandHandlingResult.of("Hi, handled exception\n", 42);
		}
		return null;
	}
}

CommandExceptionResolver implementations can be defined globally as beans:

@Bean
CustomExceptionResolver customExceptionResolver() {
	return new CustomExceptionResolver();
}

or defined per CommandRegistration if it’s applicable only to a particular command:

CommandRegistration.builder()
	.withErrorHandling()
		.resolver(new CustomExceptionResolver())
		.and()
	.build();
Resolvers defined with a command are handled before global resolvers.

You can use your own exception types which can also be instances of Spring Boot’s ExitCodeGenerator if you want to define exit code there:

static class CustomException extends RuntimeException implements ExitCodeGenerator {

	@Override
	public int getExitCode() {
		return 0;
	}
}

Some built-in CommandExceptionResolver beans are registered to handle common exceptions thrown from command parsing. These are registered with order precedence defined in CommandExceptionResolver.DEFAULT_PRECEDENCE. As these beans are used in a given order, @Order annotation or Ordered interface can be used just like in any other Spring app. This is generally useful if you need to control your own beans to get used either before or after default ones.