💡 この記事でわかること
- エラー処理とは何か、なぜ必要か
- try・catch・finallyの基本構文
- Errorオブジェクトの中身の見方
- throwで自分でエラーを発生させる方法
- 初心者がつまずきやすいポイント
1. エラー処理とは?なぜ必要か
JavaScriptのコードを実行中に、存在しない変数を参照したり、通信に失敗したりすると「エラー」が発生します。エラーが発生すると、
👉 何も対策をしていなければ、その時点でプログラムの実行が止まってしまいます。
エラー処理とは、あらかじめ「エラーが起きるかもしれない」という前提でコードを書いておき、実際にエラーが起きたときにプログラム全体を止めずに、適切なメッセージ表示や代わりの処理を行う仕組みのことです。
💡 特に、ユーザーの入力内容やネットワーク通信など「自分でコントロールできない要素」が絡む処理では、エラー処理がほぼ必須になります。
2. try・catchの基本構文
エラーが起きる可能性のある処理をtryブロックの中に書き、エラーが発生したときの処理をcatchブロックに書きます。
try {
const data = JSON.parse("これは正しいJSONではありません");
console.log(data);
} catch (error) {
console.log("エラーが発生しました:", error.message);
}
console.log("この行は実行される");
👉 tryブロックの中でエラーが発生すると、その時点でtryブロックの残りの処理はスキップされ、catchブロックの処理に移ります。catchブロックが終わったあとは、通常どおり後続の処理が実行されます。
💡 catchの引数(上の例ではerror)には、発生したエラーの情報が入ったErrorオブジェクトが渡されます。
3. finallyブロック
finallyブロックを付けると、エラーが起きても起きなくても必ず実行される処理を書けます。
try {
console.log("処理を開始します");
throw new Error("何らかのエラー");
} catch (error) {
console.log("エラー処理:", error.message);
} finally {
console.log("後片付け処理(成功でも失敗でも実行される)");
}
👉 「読み込み中のローディング表示を消す」「開いたファイルを閉じる」など、成功・失敗にかかわらず必ずやりたい後片付け処理をfinallyに書くのが定番です。
4. Errorオブジェクトの中身
catchで受け取るErrorオブジェクトには、主に次のようなプロパティが含まれています。
message:エラーの内容を表す文字列name:エラーの種類(TypeError、SyntaxErrorなど)stack:エラーが発生するまでの処理の流れを示す文字列(デバッグ時に便利)
try {
null.foo();
} catch (error) {
console.log(error.name); // "TypeError"
console.log(error.message); // "Cannot read properties of null ..."
}
5. throwで自分でエラーを発生させる
throw文を使うと、自分の判断で任意のタイミングでエラーを発生させられます。「入力値が不正な場合は処理を止める」といったチェックによく使われます。
function checkAge(age) {
if (age < 0) {
throw new Error("年齢は0以上で指定してください");
}
return age;
}
try {
checkAge(-5);
} catch (error) {
console.log(error.message); // "年齢は0以上で指定してください"
}
💡 throwするときは、文字列や数値をそのまま投げることもできますが、name・message・stackを備えたErrorオブジェクト(またはその派生)を投げるのが基本です。
6. async/awaitでのエラー処理
async関数の中では、await式をtryブロックで囲むことで、非同期処理(通信など)のエラーも同じtry/catchの書き方で扱えます。
async function fetchUser() {
try {
const response = await fetch("https://example.com/api/user");
const user = await response.json();
console.log(user);
} catch (error) {
console.log("データの取得に失敗しました:", error.message);
}
}
👉 JavaScriptの非同期処理(async/await・Promise)についての記事はこちら
7. 初心者がつまずきやすいポイント
setTimeoutやイベントリスナーの中のエラーは捕まらない
try/catchは「その場で同期的に実行される処理」のエラーしか捕まえられません。setTimeoutのコールバックやイベントリスナーの中で発生したエラーは、外側のtry/catchでは捕まえられない点に注意してください。
try {
setTimeout(() => {
throw new Error("これは外側のcatchでは捕まらない");
}, 1000);
} catch (error) {
console.log("ここには来ない");
}
👉 コールバック関数の中でエラー処理をしたい場合は、そのコールバック関数の内側にtry/catchを書く必要があります。
catchで何もしないと問題に気づけない
catchブロックを空のまま放置すると、エラーが発生していること自体に気づけなくなります。最低限console.logでエラー内容を出力するか、ユーザーにエラーメッセージを表示するようにしましょう。
try/catchの外側で宣言した変数と勘違いする
tryブロックの中でletやconstで宣言した変数は、tryブロックの外からは参照できません。tryブロックの外でも使いたい変数は、tryブロックの外側で先に宣言しておく必要があります。
まとめ
この記事では、JavaScriptのエラー処理(try・catch・finally)について解説しました。
- tryブロックにエラーが起きるかもしれない処理を、catchブロックにエラー時の処理を書く
- finallyブロックは、成功・失敗にかかわらず必ず実行される
- throwで自分の判断でエラーを発生させられる
- async関数の中ではawaitをtryで囲むことで非同期処理のエラーも扱える
- setTimeoutやイベントリスナー内のエラーは、外側のtry/catchでは捕まらない
エラー処理は地味に感じるかもしれませんが、実際のアプリ開発では欠かせない技術です。まずは通信処理やJSON.parseなど、エラーが起きやすい箇所から意識して使ってみましょう。