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 flexibility to return message to get written into 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 bean.

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

or defined per CommandRegistration if it’s applicable only for a particular command itself.

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

Use you own exception types which can also be an instance of 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 build in CommandExceptionResolver beans are registered to handle common exceptions thrown from command parsing. These are registered with order presedence defined in CommandExceptionResolver.DEFAULT_PRECEDENCE. As these beans are used in a given order, @Order annotation or Ordered interface from 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 a defaults.