はじめに
この記事では、カスタム例外を使う本質的な理由を、
- 「どの例外で何をすべきかを明確にする」
- 「ログ・UI・通知の制御を型で分離する」
という視点から整理する。
例外処理が曖昧だと、何が問題になるのか?
すべての例外を Exception
で処理したコード
try {
// 何かの処理
} catch (Exception $e) {
logError($e->getMessage());
echo "エラーが発生しました";
}
この場合、発生した例外が「入力ミス」なのか、「システム障害」なのか、「外部APIの失敗」なのかが曖昧。
その結果、以下のようになる。
- すべて同じログレベルで記録される
- エラーメッセージの内容に頼って分岐しようとする
カスタム例外を使うことで「何をすべきか」が明確になる
例外ごとに意味を持たせてクラスを分けることで、次のように意図を明示できる。
class ValidationException extends Exception {}
class DatabaseConnectionException extends Exception {}
try {
// バリデーション or DB接続処理
} catch (ValidationException $e) {
logWarning($e->getMessage());
echo "入力内容に誤りがあります";
} catch (DatabaseConnectionException $e) {
logError($e->getMessage());
notifyAdmin($e);
echo "システムエラーが発生しました";
}
このようにすることで、例外の種類ごとに処理を整理・分岐できるようになる。
例外ごとに「やるべきこと」は違う
例外クラス | 何が起きたか | 何をすべきか |
---|---|---|
ValidationException |
入力内容に問題がある | ユーザーにエラーメッセージを表示+warningログ |
AuthenticationException |
認証情報が不正 | ログイン画面に遷移+infoログ |
DatabaseConnectionException |
DBが落ちている、接続できない | errorログ+Slack通知+再接続リトライ |
Throwable (その他) |
想定外のバグやエラー | criticalログ+500エラー画面+運用対応 |
これが、「例外とはただのエラーではなく、意味のあるイベント」である、という考え方。
まとめ
単に動けば良いと考えるのではなく、「例外をどう扱うか」を考えることが重要。
- どの例外が起きたら、何をすべきか?
- 誰に通知し、どのログに残し、どのようなUIやレスポンスにするか?
これを明確にできる設計が、カスタム例外の本当の価値。