TypeScriptの例外処理で再スロー(rethrow)を使いこなす!エラーハンドリングの基礎知識
生徒
「TypeScriptでプログラムを書いていると、エラーが発生した時にどう対処していいか悩みます。例外を一度受け取って、また投げるようなことはできますか?」
先生
「それは再スロー(rethrow)という技術ですね。エラーが発生した時に、ログを残してから、もう一度そのエラーを外側に伝える方法です。」
生徒
「なぜ、わざわざもう一度投げる必要があるんですか?」
先生
「それでは、初心者の方でもわかるように、基本的な仕組みから再スローの必要性まで解説していきましょう!」
1. プログラミングにおけるエラーハンドリングとは何か
プログラミングをしていると、どうしても避けられないのがエラーです。例えば、インターネットに繋がらない環境でデータを読み込もうとしたり、存在しないファイルを開こうとしたりすると、プログラムは正常に動けなくなります。これを「例外」と呼びます。
エラーハンドリングとは、そうした予期せぬトラブルが発生した時に、プログラムをいきなり止めるのではなく、丁寧に対応して、ユーザーに対してわかりやすいメッセージを表示したり、安全に終了させたりする仕組みのことです。初心者の方は、まずはこの「エラーを安全に処理する」という考え方を覚えることが、バグの少ないTypeScriptコードを書く第一歩となります。
2. try-catch文でエラーを捕まえる基本
TypeScriptで例外を処理する際の基本は「try-catch(トライキャッチ)文」です。これは、「とりあえず実行してみる(try)」と「もしダメだったらこちらで対応する(catch)」という二段構えの命令です。
まずは、エラーが起きる可能性のあるコードをtryブロックの中に書き、エラーが起きた時に動くコードをcatchブロックに書くという基本の形を覚えましょう。
try {
// ここでエラーが起きるかもしれない処理を実行する
throw new Error("何か問題が発生しました!");
} catch (error) {
// ここでエラーを受け取って処理する
console.log("エラーを検知しました");
}
このように書くと、プログラムが突然落ちるのを防ぎ、エラーの内容に応じた対応をとることができます。
3. 再スロー(rethrow)が必要な理由
では、なぜわざわざ一度catchしたエラーを、もう一度外側に投げる必要があるのでしょうか。それは、「この場所ではログだけ記録して、具体的な対処は別の場所に任せたい」という場合があるからです。
例えば、データを保存する関数の中でエラーが起きたとします。その関数はエラーの記録だけは行いたいけれど、プログラム全体としてエラーを止めるべきかどうか判断するのは、その関数を呼び出した側の責任である場合が多いのです。このような時に、catchしたエラーをそのまま再び「投げる(スローする)」のが再スローの役割です。
4. throwキーワードで再スローを実装する
再スローを実装するのは非常に簡単です。catchブロックの中で、受け取ったエラー変数をそのまま「throw」するだけです。
function saveData() {
try {
// 何かエラーを発生させる処理
throw new Error("データベース接続失敗");
} catch (error) {
// エラーログを記録する
console.error("保存失敗のログを残します:", error);
// もう一度同じエラーを投げる
throw error;
}
}
こうすることで、この関数を呼び出した側は「あ、この関数はエラーを解決できなかったんだな」と判断して、さらに別の対応を行うことができます。
5. 実践的なエラー情報の受け渡しと設計方法
実務レベルのTypeScript開発では、単にエラーを投げるだけでなく、エラーの型を細かく分類することをおすすめします。そうすることで、何が起きたのかが明確になります。
class DatabaseError extends Error {
constructor(message: string) {
super(message);
this.name = "DatabaseError";
}
}
try {
throw new DatabaseError("接続がタイムアウトしました");
} catch (error) {
if (error instanceof DatabaseError) {
console.log("データベース専用のエラー処理です");
}
// エラーの種類に関わらず再スローして上位に知らせる
throw error;
}
このように、独自のエラークラスを作ることで、どの階層で何のエラーが起きたのかをより正確に追いかけることが可能になります。これは大規模なWebアプリケーションを開発する際に非常に重要なテクニックとなります。
6. 注意すべきポイントとプログラミングの心得
例外処理を書く際に一つ注意点があります。それは「全ての箇所で再スローを使いすぎない」ことです。もし、すべての関数でエラーを再スローし続けると、最終的にどこでエラーを食い止めるのかがわからなくなってしまいます。
基本的には「エラーの詳細を隠さず、一番適切な階層で解決する」ことを意識してください。エラーが発生した時に、そのエラーが自分の責任範囲内で解決できるのか、それとも上位のプログラムに伝えて対応をお願いすべきなのかを見極める判断力が、プログラマーとしてのスキルを向上させます。この「どこで処理するのか」の設計をしっかり考えることが、読みやすく、堅牢なTypeScriptコードへの近道です。