例外処理

コマンドを記述する際には、エラー発生時にアプリケーションが予測どおりに動作することを保証するために、例外を適切に処理することが重要です。Spring Shell では、ExitStatusExceptionMapper インターフェースにより、例外を効果的に管理し、特定の終了コードとユーザーフレンドリーなメッセージにマッピングできます。

ExitStatusExceptionMapper インターフェースは、コマンド実行中にスローされた例外を特定の終了コードとメッセージにマッピングする方法を提供します。このインターフェースを実装することで、様々な例外の種類に対してカスタム動作を定義でき、ユーザーに有益なフィードバックを提供し、アプリケーションの終了ステータスを制御できるようになります。

ExitStatusExceptionMapper の実装

ExitStatusExceptionMapper は java.util.Function を継承した関数型インターフェースで、Exception を入力として受け取り、ExitStatus を返します。このメソッドを実装することで、特定の例外を処理し、適切な終了コードとメッセージを返すことができます。たとえば、次のようになります。

@Bean
public ExitStatusExceptionMapper myCustomExceptionMapper() {
	return exception -> new ExitStatus(42, "42! The answer to life, the universe and everything!");
}

マッパーの登録

プログラムによる登録

プログラムでコマンドを登録する場合、Command.Builder の exitStatusExceptionMapper メソッドを使用して ExitStatusExceptionMapper を設定できます。例:

@Bean
public Command sayHello() {
	return Command.builder()
			.name("hello")
			.description("Say hello to a given name")
			.group("Greetings")
			.help("A command that greets the user with 'Hello ${name}!'. Usage: hello [-n | --name]=<name>")
			.exitStatusExceptionMapper(exception -> new ExitStatus(42, "42! The answer to life, the universe and everything!"))
			.execute(context -> {
				String name = context.getOptionByName("name").value();
				if (name.equals("42")) {
					throw new RuntimeException("Error!");
				}
				System.out.println("Hello " + name + "!");
			});
}

アノテーションベースの登録

アノテーションベースのコマンド登録を使用する場合、@Command アノテーションの exitStatusExceptionMapper 属性を使用してカスタム ExitStatusExceptionMapper を指定できます。例:

@Command(name = "hello", description = "Say hello to a given name", group = "Greetings",
		help = "A command that greets the user with 'Hello ${name}!'. Usage: hello [-n | --name]=<name>",
		exitStatusExceptionMapper = "myCustomExceptionMapper")
public void sayHello(@Option(shortName = 'n', longName = "name", description = "the name of the person to greet",
		defaultValue = "World") String name) {
	if (name.equals("42")) {
		throw new RuntimeException("Error!");
	}
	System.out.println("Hello " + name + "!");
}

@Bean
public ExitStatusExceptionMapper myCustomExceptionMapper() {
	return exception -> new ExitStatus(42, "42! The answer to life, the universe and everything!");
}

カスタムマッパーは、@Command アノテーションで名前によって参照できるように、Spring Bean として定義する必要があります。