Programming Self-Study Notebook

勉強したことを忘れないように! 思い出せるように!!

JavaScriptの文法(例外とエラー処理)

f:id:overworker:20200406080809j:plain:h250

Errorオブジェクト

// インスタンスの生成
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する

例外処理とコールスタック

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)
  */
}
  • .stackthrowの実行場所、及びthrowまでの経緯を確認することができる。

try...catch...finally

Errorの発生の有無にかかわらず必ず実施しなけらばならない処理(必ず実施したい処理)はfinallyに記述する

console.log('処理を開始します');
try{
  a();
  console.log('この行は例外発生時は処理されません');
} catch (err){
  console.log('Catch Exception');
} finally {
  console.log('処理を終了します');
}

例外処理は例外に限る

  • 例外は正しく処理されないとプログラムがクラッシュすることもある。
  • 例外処理のコストは馬鹿にならない。

参考文献