LoginSignup
4
1

More than 1 year has passed since last update.

例外処理の原則 "Throw early, catch late"

Last updated at Posted at 2023-01-09

例外の原則で有名な"Throw early, catch late"の紹介です。1

ざっくり説明

Throw early(早く投げろ)

  • 例外的な状況になったらさっさと例外をThrowしよう

Catch late(後でキャッチしろ)

  • 例外をハンドリングするのは、例外をどうハンドリングすべきかを知っている場所でやろう
  • どうハンドリングすべきかを知らない場所では余計なことをしちゃダメ

具体例を交えて説明

なぜThrow earlyなのか

例外的な状況に遭遇したら処理を続行できるわけがないため。(至極当然な話をしています)

Throw earlyをちゃんとやっている例

public class FileUtil {
    /** 指定されたパスのファイルを全部読み込んで文字列で返す。*/
    public static String readAll(String path) {
        if (path == null) {
             throw new NullPointerException("パスが指定されてないからファイルを読み込めるわけがないよ。。。");
        }

        if (!Files.exists(path)) {
        	throw new FileNotFoundException("指定されたファイルが存在しないからファイルを読み込めるわけがないよ。。。");
        }

        // 以下略
    }
}

なぜCatch lateなのか

基本的に例外をどうハンドリングすべきかを知っているのは呼び出し元(上位層)であるため

前出のFileUtil#readAll(path)にとっては、指定されたファイルが存在しないという状況は処理が続行できない状況(つまり例外的な状況)でした。
しかしながらFileUtil#readAll(path)を呼び出している上位層にとっては、ファイルが存在しないのは想定済みの状況(つまり処理が続行できる状況)かもしれません。↓

public class BusinessLogic {
    /** 
     * `hoge.txt`の中身を標準出力する。
     * `hoge.txt`が存在しなければ`Not exist.`と標準出力する。
     */
    public static void execute() {
         try {
             String text = FileUtil.readAll("hoge.txt");
             System.out.println(text);

         } catch (FileNotFoundException e) { // ファイルが存在しなかった場合
             System.out.println("Not exist.");
         }
    }
}

このような状況でもしFileUtil#readAll(path)で余計なハンドリングをしてしまった場合、色々と問題が起きてしまいます

余計なハンドリングの例

例外をThrowせずにプロセスを停止する
    public static String readAll(String path) {
        // 中略
        if (!Files.exists(path)) {
        	System.exit(1);
        }
        // 後略
    }

プロセスを停止してしまったら業務が遂行できません。(本当はNot exist.と標準出力するのが正解なのに。。。)

エラーログを出力してから例外をThrow
    public static String readAll(String path) {
        // 中略
        if (!Files.exists(path)) {
        	LOGGER.error("指定されたファイルが存在しません!");
        	throw new FileNotFoundException("指定されたファイルが存在しないからファイルを読み込めるわけがないよ。。。");
        }
        // 後略
    }

もしシステムが「エラーログを検知したら即座にエンジニアに連絡!」みたいな仕組みになっていた場合、業務的には問題ないハズなのにエンジニアに連絡が来るようになってしまいます。

まとめ

  • 例外的な状況になったらさっさと例外をThrowする。
  • 例外をどうハンドリングすればわからないときは上位層に任せる。 余計なことはしない。

おすすめ記事

記事を書いてみた感想

プライベートな時間を使ってコンスタントにアウトプットし続けられる人って本当にすごい。 えらすぎる。

  1. 有名だと思ってたけど意外と日本語の記事がなかったので書いてみた。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1