Errorオブジェクト
- JavaScriptに用意されているオブジェクト
- インスタンスを生成するだけでは何も起こらない
// インスタンスの生成 const err = new Error('エラーを検出しました。');
以下はサブルーチンで実際にErrorオブジェクトを返却する例です。
// Email Addressに対するバリデーションを実施する function validateEmail(email){ if (email.match(/@/)){ return email; } else { if (email === 'no_message'){ return new Error(); } else if(email === 'empty_message'){ return new Error(''); } else { return new Error(`Email Address Invalid:${email}`); } } } function checkResult(result){ if(result instanceof Error){ if(result.message){ return result.message; } else { if (result.message === null){ return 'null'; } else if (result.message === ''){ return 'empty'; } else if (result.message === undefined){ return 'undefined!'; } else if (result.message === 0){ return 0; } } } else { return `Email Address OK!:${result}`; } } let email = ""; let validatedEmail = {}; email = "no_message"; validatedEmail = validateEmail(email); console.log(checkResult(validatedEmail)); // empty email = "empty_message"; validatedEmail = validateEmail(email); console.log(checkResult(validatedEmail)); // empty email = "test_gmail.com"; validatedEmail = validateEmail(email); console.log(checkResult(validatedEmail)); // Email Address Invalid:test_gmail.com email = "test@gmail.com"; validatedEmail = validateEmail(email); console.log(checkResult(validatedEmail)); // Email Address OK!:test@gmail.com
上記例からわかったこと
- サブルーチン等からエラーが返ってきていないことを確認するにはinstanceof
を使用する
- エラーオブジェクトのインスタンスに何もセットしなかった場合、.message
は''(空文字列)
相当
例外処理(try...catch)
let email = ""; let validatedEmail = {}; try { email = null; validatedEmail = validateEmail(email); console.log(checkResult(validatedEmail)); // 実行されない } catch { console.log(`catch Exception :${email}`); // catch Exception :null }
- エラーをキャッチしているので、プログラムは停止しない。
- エラーを記録してプログラムを継続する。
例外のスロー
JavaScript
では任意の値(数値、文字列、オブジェクト等)をthrow
することが可能- 一般的(慣例的)にはErrorオブジェクトのインスタンスを
throw
する
- 一般的(慣例的)にはErrorオブジェクトのインスタンスを
例外処理とコールスタック
function a (){ console.log('a:開始'); // 出力あり b(); console.log('a:終了'); // 出力無し } function b (){ console.log('b:開始'); // 出力あり c(); console.log('b:終了'); // 出力無し } function c (){ console.log('c:開始'); // 出力あり throw new Error('c error'); console.log('c:終了'); // 出力無し } console.log('処理を開始します'); try{ a(); console.log('処理を終了します'); } catch (err){ console.log('----------------Catch Exception'); console.log(`err.message:${err.message}`); // err.message:c error console.log('--err.stack:'); console.log(`${err.stack}`); /* Error: c error at c (main.js:22) at b (main.js:17) at a (main.js:12) at HTMLButtonElement.<anonymous> (main.js:28) */ }
.stack
にthrow
の実行場所、及びthrow
までの経緯を確認することができる。
try...catch...finally
Errorの発生の有無にかかわらず必ず実施しなけらばならない処理(必ず実施したい処理)はfinally
に記述する
console.log('処理を開始します'); try{ a(); console.log('この行は例外発生時は処理されません'); } catch (err){ console.log('Catch Exception'); } finally { console.log('処理を終了します'); }
例外処理は例外に限る
- 例外は正しく処理されないとプログラムがクラッシュすることもある。
- 例外処理のコストは馬鹿にならない。