JavaScript | throw文

JavaScript
スポンサーリンク

では 初心者向けに分かりやすく、たくさんの例題付きで throw を含む例外(エラー)の扱いを詳しく説明します。実行結果イメージや練習問題(解答付き)まで付けます。

1) まずは「例外(exception)って何?」を超かんたんに

プログラムが“いつも通り進めない状態”になったときに、処理を中断して特別な流れに飛ばす仕組みが 例外 です。
throw は「ここで問題発生!例外を投げるよ(発生させるよ)」という命令、try…catch は「例外が起きたときの受け皿」です。

2) 基本:throw と try…catch

try {
  throw '何か問題が起きた';  // 例外を投げる
  console.log('この行は実行されません');
} catch (e) {
  console.log('例外をキャッチしました:', e);
}
JavaScript

実行の流れ:

  1. throw で例外を発生 → その時点で後ろの処理は飛ばされる。
  2. 近くの try に対応する catch に処理が移り、e に投げられた値が入る。

throw に渡すものは何でもOK(文字列、数値、オブジェクト、Error オブジェクトなど)。

3) なぜ Error オブジェクトを使うのが良いのか

new Error('メッセージ') にすると、「どこでどんなエラーか」が分かりやすく、スタックトレース(どの関数で発生したかの履歴)も付くのでデバッグしやすくなります。

try {
  throw new Error('この処理はできません');
} catch (err) {
  console.log(err.name);    // "Error"
  console.log(err.message); // "この処理はできません"
  console.log(err.stack);   // どの行で発生したか分かる(開発で便利)
}
JavaScript

4) 具体例 1:入力チェックで使うパターン(関数内部で throw)

function divide(a, b) {
  if (b === 0) {
    throw new Error('0で割ることはできません');
  }
  return a / b;
}

try {
  console.log(divide(10, 2)); // 5
  console.log(divide(3, 0));  // ここで例外が発生し、catchへ
} catch (e) {
  console.error('エラー:', e.message);
}
JavaScript

ポイント:関数内で検査して「不正」なら throw → 呼び出し元は try…catch で受け取れる。

5) 具体例 2:文字列や数値でも投げられる(でも注意)

try {
  throw 'これは文字列の例外';
} catch (e) {
  console.log(typeof e, e); // "string", "これは文字列の例外"
}
JavaScript

ただし、型がばらばらだと扱いにくくなるので実務では Error を投げるのが標準的です。

6) try…catch…finally — 最後に必ず実行したい処理

finally ブロックは、例外が起きても起きなくても必ず実行されます(リソース解放などに便利)。

try {
  console.log('処理開始');
  throw new Error('問題発生');
} catch (e) {
  console.log('catch:', e.message);
} finally {
  console.log('必ず実行される処理(例:接続を閉じる)');
}
JavaScript

出力イメージ:

処理開始
catch: 問題発生
必ず実行される処理(例:接続を閉じる)

7) 例外を再スロー(catch で処理してももう一度投げる)

時には catch で一部対応したあと、呼び出し元にまた例外を伝えたいことがあります。

function parseAndCompute(jsonStr) {
  try {
    const obj = JSON.parse(jsonStr);
    if (!obj.value) throw new Error('valueがありません');
    return obj.value * 2;
  } catch (e) {
    console.log('内部でログ:', e.message);
    throw e; // 呼び出し元に再度投げる
  }
}

try {
  parseAndCompute('{"bad":1}');
} catch (e) {
  console.log('呼び出し元で受けた:', e.message);
}
JavaScript

8) カスタムエラークラス(より良いエラーハンドリング)

JavaScript では class を使って独自のエラー型を作れます。種類ごとに処理を分けたいときに便利。

class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = 'ValidationError';
  }
}

function validate(name) {
  if (!name) throw new ValidationError('名前が必要です');
}

try {
  validate('');
} catch (e) {
  if (e instanceof ValidationError) {
    console.log('入力エラー:', e.message);
  } else {
    console.log('その他のエラー:', e.message);
  }
}
JavaScript

9) 非推奨な使い方・注意点

  • 日常的な制御に例外を多用しない:例外は「特別な状況」に使うもの。普通の条件分岐は if で行う。
  • 無意味に投げると可読性が下がる。
  • throw したら必ずどこかで捕捉するか、呼び出し元で扱う設計にする(未捕捉だとプログラムが止まる)。

10) 練習問題

問題1isAdult(age) 関数を作る。age が 20 未満なら throw new Error('未成年です') し、それ以外は "OK" を返す。呼び出して try…catch で結果をログに出す。
解答1(サンプル)

function isAdult(age) {
  if (age < 20) throw new Error('未成年です');
  return 'OK';
}

try {
  console.log(isAdult(25)); // OK
  console.log(isAdult(17)); // ここで例外
} catch (e) {
  console.log('キャッチ:', e.message);
}
JavaScript

問題2safeJSONParse(str) を作って、JSON.parse で例外が出たら null を返す。成功したらオブジェクトを返す。
解答2(サンプル)

function safeJSONParse(str) {
  try {
    return JSON.parse(str);
  } catch (e) {
    return null;
  }
}

console.log(safeJSONParse('{"a":1}')); // { a: 1 }
console.log(safeJSONParse('不正なJSON')); // null
JavaScript

問題3(少し応用)readFile(filePath) を模した関数で、ファイルが見つからない(filePath === '' など)場合は throw new Error('ファイルが見つかりません')。呼び出し側で種類別に処理(ファイルエラーなら別メッセージ、その他は再スロー)するコードを書いてみよう。
(解答の要点:try 内で readFile を呼び、catche.message を判定。想定外なら throw e; で再スロー。)

まとめ(初心者が覚えるべき最重要ポイント)

  • throw で例外を発生させ、try…catch で受け取る。
  • 投げる値は何でも良いが、new Error('説明') を使うのが実務的に便利。
  • finally は「必ず実行したい処理」に使う。
  • 例外は便利だが乱用は禁物。入力チェックや予期しない状態で使うのが基本。
タイトルとURLをコピーしました