【初心者必見】JavaScriptエラー処理の基本をマスター!挫折しない5つのステップ
こんにちは、とまだです。
JavaScriptを学習していて、「エラーが出るたびに心が折れそう」と感じたことはありませんか?
実は私も最初、赤い文字のエラーメッセージを見るたびに「もう無理かも...」と思っていました。
でも大丈夫です。エラー処理を理解すれば、エラーは「敵」ではなく「味方」になります。
今回は、JavaScriptのエラー処理を「保険」に例えながら、誰でも理解できるように解説していきます。
エラー処理とは?保険に例えて理解しよう
JavaScriptのエラー処理って、難しそうですよね。
でも実は、日常生活の保険と同じようなものなんです。
車を運転するとき、万が一の事故に備えて保険に入りますよね。
同じように、プログラムも「万が一エラーが起きたとき」に備えて、対策を準備しておくんです。
エラー処理をしないプログラムは、保険なしで車を運転するようなもの。
ちょっとした問題で、プログラム全体がストップしてしまいます。
なぜエラー処理が必要なの?
「そもそも、エラーが起きないプログラムを書けばいいのでは?」
そう思うかもしれません。
でも現実は、どんなに注意深くプログラムを書いても、予期しないエラーは起きてしまうんです。
例えば、ユーザーが予想外の入力をしたり、ネットワークが一時的に切断されたり。
こうした「想定外」の状況でも、プログラムが正常に動き続けるために、エラー処理が必要なんです。
実際のWebサービスを想像してみてください。
Amazonで買い物中に、商品画像が一つ読み込めなかったからといって、サイト全体が真っ白になったら困りますよね。
適切なエラー処理があれば、「画像を読み込めませんでした」と表示しつつ、他の機能は使い続けられます。
try-catch-finallyの基本を理解しよう
JavaScriptのエラー処理の基本は、try-catch-finallyという仕組みです。
これを日常生活で例えると、こんな感じです。
- try = 挑戦する(料理を作ってみる)
- catch = 失敗したときの対処(焦げたら作り直す)
- finally = 最後に必ずやること(キッチンを片付ける)
実際のコードで見てみましょう。
try {
// ここにエラーが起きるかもしれない処理を書く
const result = riskyOperation();
console.log("成功しました!");
} catch (error) {
// エラーが起きたときの処理
console.log("エラーが発生しました:", error.message);
} finally {
// 成功でも失敗でも必ず実行される
console.log("処理が終了しました");
}
このコードは、「riskyOperation」という処理を実行し、エラーが起きたらキャッチして、最後に必ず終了メッセージを表示します。
tryブロックの役割
tryブロックは、「この中でエラーが起きるかもしれない」という処理を囲む場所です。
例えば、ユーザーの入力を数値に変換する処理などを入れます。
try {
const userInput = "abc"; // ユーザーが入力した文字
const number = parseInt(userInput);
if (isNaN(number)) {
throw new Error("数値を入力してください");
}
}
ここでthrowという新しいキーワードが出てきました。
これは「エラーを投げる」という意味で、意図的にエラーを発生させるときに使います。
catchブロックでエラーをキャッチ
catchブロックは、tryブロック内でエラーが発生したときに実行されます。
エラーの情報はerrorという変数(名前は自由に決められます)に入ってきます。
catch (error) {
// エラーの種類によって処理を分ける
if (error.message.includes("数値")) {
alert("数値を入力してください");
} else {
alert("予期しないエラーが発生しました");
}
}
エラーオブジェクトにはmessageプロパティがあり、エラーの詳細情報が入っています。
これを使って、ユーザーに分かりやすいメッセージを表示できます。
finallyブロックの活用方法
finallyブロックは、成功・失敗に関わらず必ず実行されます。
リソースの解放や、ローディング表示を消すなど、「後片付け」的な処理を書くのに便利です。
let isLoading = true;
try {
// データを取得する処理
const data = await fetchData();
displayData(data);
} catch (error) {
displayError("データの取得に失敗しました");
} finally {
// 成功でも失敗でも、ローディング表示は消す
isLoading = false;
hideLoadingSpinner();
}
よく遭遇するエラーの種類と対処法
JavaScriptでよく見かけるエラーには、いくつかのパターンがあります。
それぞれの特徴と対処法を理解しておくと、デバッグが楽になりますよ。
TypeError(型エラー)
最もよく見るエラーの一つです。
「存在しないメソッドを呼び出そうとした」「nullやundefinedのプロパティにアクセスした」といった場合に発生します。
よくある例を見てみましょう。
// よくあるTypeError
const user = null;
console.log(user.name); // TypeError: Cannot read property 'name' of null
このエラーを防ぐには、アクセスする前にチェックする習慣をつけましょう。
// 安全なアクセス方法
if (user && user.name) {
console.log(user.name);
}
// より現代的な書き方(オプショナルチェーン)
console.log(user?.name);
ReferenceError(参照エラー)
宣言されていない変数を使おうとしたときに発生します。
スペルミスが原因のことが多いので、変数名を再確認しましょう。
// ReferenceErrorの例
console.log(userName); // ReferenceError: userName is not defined
// 正しい書き方
const userName = "田中太郎";
console.log(userName);
SyntaxError(構文エラー)
JavaScriptの文法に違反したときに発生します。
閉じ括弧の忘れや、セミコロンの位置間違いなどが原因です。
// SyntaxErrorの例
if (true { // 閉じ括弧がない
console.log("エラーになります");
}
// 正しい書き方
if (true) {
console.log("正常に動きます");
}
構文エラーは、コードエディタの構文チェック機能で事前に発見できることが多いです。
VSCodeなどのエディタを使っていれば、赤い波線で教えてくれます。
エラー処理のベストプラクティス
ここまでで基本は理解できたと思います。
では、実際の開発で使える、より実践的なテクニックを見ていきましょう。
エラーの種類に応じた処理
すべてのエラーを同じように扱うのではなく、種類に応じて適切に処理することが大切です。
try {
await saveUserData(userData);
} catch (error) {
if (error.name === 'ValidationError') {
// 入力値が不正な場合
showValidationMessage(error.message);
} else if (error.name === 'NetworkError') {
// ネットワークエラーの場合
showRetryButton("通信エラーが発生しました");
} else {
// その他の予期しないエラー
console.error(error);
showGenericError();
}
}
エラーの種類によって、ユーザーへの表示方法を変えることで、より親切なアプリケーションになります。
カスタムエラーの作成
標準のErrorオブジェクトだけでなく、独自のエラークラスを作ることもできます。
これにより、エラーの種類をより明確に区別できるようになります。
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = 'ValidationError';
}
}
// 使用例
function validateEmail(email) {
if (!email.includes('@')) {
throw new ValidationError('メールアドレスが正しくありません');
}
}
カスタムエラーを使うことで、エラーハンドリングがより整理されたコードになります。
非同期処理でのエラーハンドリング
最近のJavaScriptでは、async/awaitを使った非同期処理が主流です。
非同期処理でのエラーハンドリングも、基本的にはtry-catchで行います。
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTPエラー: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('ユーザーデータの取得に失敗:', error);
// デフォルト値を返すか、エラーを再度投げる
return null;
}
}
非同期処理では、ネットワークエラーやタイムアウトなど、様々なエラーが発生する可能性があります。
適切にエラーハンドリングすることで、ユーザー体験を損なわないアプリケーションを作れます。
まとめ:エラーを恐れずに前進しよう
ここまで、JavaScriptのエラー処理について詳しく見てきました。
最初は難しく感じるかもしれませんが、基本的な考え方はシンプルです。
- エラーは必ず起きるものと考える
- try-catch-finallyで適切に処理する
- エラーの種類に応じて対応を変える
- ユーザーに分かりやすいメッセージを表示する
エラー処理をマスターすれば、より堅牢なアプリケーションが作れるようになります。
そして何より、エラーが怖くなくなります。
私も最初はエラーメッセージを見るたびにビクビクしていました。
でも今では、エラーは「プログラムを改善するためのヒント」だと思えるようになりました。
もしJavaScriptの学習でつまずいている方は、ぜひLearning Nextのカリキュラムも覗いてみてください。
JavaScriptの基礎から、エラー処理を含む実践的な内容まで、体系的に学べるようになっています。
特に、豊富な練習問題で実際に手を動かしながら学べるので、理解が深まりやすいはずです。
プログラミング学習は、一人で悩まず、適切な教材と一緒に進めることが成功への近道です。
エラーを恐れず、一緒にJavaScriptマスターを目指しましょう!
著者について

とまだ
フルスタックエンジニア
Learning Next の創設者。Ruby on Rails と React を中心に、プログラミング教育に情熱を注いでいます。初心者が楽しく学べる環境作りを目指しています。
著者の詳細を見る →