throw 文で例外を投げる|JavaScript
throw 文を使うと、意図的にエラーを発生させることができます。入力値のチェックや、予期しない状態の検出など、プログラムを安全に保つために欠かせない機能です。
基本構文
throw 式;throw の後には任意の値を指定できますが、通常は Error オブジェクトを投げます。
throw new Error('エラーが発生しました');入力値のバリデーション
関数の引数が期待する値でない場合、早めにエラーを投げることで問題を明確にできます。
function divide(a, b) {
if (b === 0) {
throw new Error('0で割ることはできません');
}
return a / b;
}
try {
console.log(divide(10, 0));
} catch (error) {
console.error(error.message); // "0で割ることはできません"
}エラーを投げずに処理を続けると、NaN や Infinity といった予期しない値が後続の処理に紛れ込む恐れがあります。
適切なエラー型を選ぶ
状況に応じた組み込みエラー型を使うと、エラーの原因がより明確になります。
function setVolume(level) {
if (typeof level !== 'number') {
throw new TypeError('level は数値で指定してください');
}
if (level < 0 || level > 100) {
throw new RangeError('level は 0〜100 の範囲で指定してください');
}
console.log(`音量を ${level} に設定しました`);
}TypeError
引数の型が間違っている場合に使用
RangeError
値が有効範囲外の場合に使用
throw で投げられるもの
throw は Error 以外の値も投げられます。
throw 'エラーです'; // 文字列
throw 404; // 数値
throw { code: 'E001' }; // オブジェクト
throw null; // nullただし、Error オブジェクト以外を投げると stack プロパティが得られず、デバッグが困難になります。実務では必ず Error オブジェクトを使いましょう。
throw と return の違い
throw は関数の実行を中断してエラーを上位に伝播させます。return とは根本的に異なる動作です。
function checkAge(age) {
if (age < 0) {
throw new Error('年齢は0以上である必要があります');
}
return age;
}throw が実行されると、その関数内の後続のコードは実行されません。また、呼び出し元で try-catch がなければ、プログラム全体が停止します。
再スロー(rethrow)
catch で一度エラーを捕捉した後、再度投げ直すことも可能です。
try {
riskyOperation();
} catch (error) {
console.error('エラーをログに記録:', error.message);
throw error; // 再スロー
}ログを記録しつつ、上位の呼び出し元にもエラーを伝えたい場合に使います。
条件付きでエラーを再スロー
特定のエラーだけを処理し、それ以外は再スローするパターンもよく使われます。
try {
doSomething();
} catch (error) {
if (error instanceof TypeError) {
console.log('型エラーを処理しました');
} else {
throw error; // 他のエラーは上位へ
}
}こうすることで、関心のあるエラーだけを処理し、想定外のエラーは呼び出し元に任せることができます。