例外処理
Exception Handling
例外処理は、通常の戻り方から外れて伝えられた失敗などを捕捉し、対処や後始末を行う仕組みです。例外は予測不能な問題だけに限らず、無効な入力やファイル読込の失敗など、想定して扱うものもあります。
🐾 猫で例えると?
ハンモックで上を見上げ、両前足を構える茶トラ。もし遊んでいる途中で何かが落ちてきたら、いつもの動きを止めて受け止める、と想像してみましょう。例外処理も、通常の処理で問題が起きたときに、別に用意した対応へ移る仕組みです。受け止めた後に続けるか、中止するかまで考える点も対応します。
💻 アプリ・Web開発における「例外処理」とは?
システムは、ネットワークの一時的な切断、データベースの応答遅延、ユーザーの予期せぬ入力など、開発時には完璧に予測しきれない様々な「想定外の事態」に直面します。これらに対して何の対策もしていないと、アプリは突然フリーズしたり、画面が真っ白になったりして、ユーザーの信頼を大きく損ないます。
どの場所で回復できるかを決め、必要な境界で例外を捕捉します。エラーを表示するだけで整合性が元に戻るとは限りません。変更途中のデータや再試行可能性も確認し、回復できない例外は上位へ伝える設計にします。
⚠️ 例外処理の仕組みと注意点
多くのプログラミング言語では `try-catch` (または `try-except`)という構文を使います。「とりあえずこの処理をやってみて(try)、もしエラーが出たらここで捕まえて(catch)ね」という分かりやすい仕組みです。
// JavaScript:壊れたJSONを読み込む例
try {
const cat = JSON.parse("これはJSONではありません");
console.log(cat.name);
} catch (error) {
if (error instanceof SyntaxError) {
console.log("データの形式を読み取れませんでした");
} else {
throw error; // この場所で扱えない失敗は上位へ
}
} finally {
console.log("読込処理を終えます");
} finallyは通常、成功・例外・returnのいずれでも制御が抜ける前に実行されます。ただしプロセスの強制終了や電源断まで保証するものではありません。またfinally内のreturnやthrowが元の結果を上書きする点にも注意します。
🛠️ 例外処理を賢く使うためのポイント
例外処理は非常に便利ですが、使い方を間違えると後から取り返しのつかない負債(バグの温床)になります。
- 例外のもみ消しをしない: `catch` の中で何も処理を書かないと、エラーが起きた事実そのものが闇に葬られ、後から原因を追うための手掛かりが失われます。アメショに可愛い顔で誤魔化されても、システムログだけはしっかり残さなければいけません。
- 言語の捕捉方法を確認: JavaScriptは一つのcatch内でinstanceofなどを使って必要な種類を分けます。非同期処理の失敗は、対象Promiseをawaitするかcatchを付けて扱います。後で実行される別のコールバックの例外は、外側のtryで自動的に捕捉できません。
- APIの契約に合わせる: 失敗を値で返すAPIも、例外を投げるAPIもあります。予測できる失敗は絶対に例外にしない、と決めつけず、呼び出し側が区別して処理できる形へそろえます。
両前足を構える茶トラのように、例外処理では失敗に備えます。捕まえた後に続行するのか、中止するのか、利用者へ何を伝えるのかを決めましょう。原因を追える情報を残すことも、単にエラー表示を消すことと区別したい点です。