unhurried

コンピュータ関連ネタがほとんど、ときどき趣味も…

JavaScript エラー処理(独自エラー・条件分岐)

Javaで例外処理と言えば、Exceptionクラスを継承したクラスを定義して、instanceof演算子で条件分岐するのが定番です。JavaScriptの定番について調べてみたところ、大きくは下記の2パターンがあるようです。

  1. Errorオブジェクトを継承する

    • Errorオブジェクトを継承したクラス(ES5以前の場合はprototypeを継承したオブジェクト)を定義して、instanceof演算子で条件分岐します。
    • instanceof演算子で比較するため、文字列比較と異なり確実に比較ができますが、条件分岐をするコードでも独自Errorクラス(オブジェクト)をロードする必要があります。
  2. Errorオブジェクトのnameプロパティを変更する

    • Errorオブジェクトを生成して、nameプロパティを変更して、nameプロパティに設定した文字列一致で条件分岐します。
    • 手軽に記述できる一方、文字列一致のため予期せず依存するモジュールに定義されているエラーとnameプロパティが重なってしまう可能性があります。

サンプルコード

error.js

var ERROR = {};

// Errorを継承したままではnameプロパティは「Error」のままであるため、
// nameプロパティを独自のエラークラスの名称に変更する。
ERROR.Error1 = class extends Error {}
ERROR.Error1.prototype.name = "Error1";

// ES5以前の場合はprototypeを使って継承する。
ERROR.Error2 = function (message) {
    this.message = message;
}
ERROR.Error2.prototype = new Error;
ERROR.Error2.prototype.name = "Error2";

module.exports = ERROR;

module.js

const ERROR = require('./error.js');

class MyClass {
    static myMethod(arg) {
        if (arg === 1) {
            throw new ERROR.Error1("Error1 occured.")
        } else if (arg === 2) { 
            throw new ERROR.Error2("Error2 occured.")
        } else if (arg === 3) { 
            const e = new Error("Error3 occured.")
            e.name = "Error3";
            throw e;
        }
    }
}

module.exports = MyClass;

main.js

const MyClass = require('./module.js');
const ERROR = require('./error.js');

try {
    MyClass.myMethod(1);
} catch(e) {
    if (e instanceof ERROR.Error1) {
        console.log(e.name);
        console.log(e.message);
    }
}

try {
    MyClass.myMethod(2);
} catch(e) {
    if (e instanceof ERROR.Error2) {
        console.log(e.name);
        console.log(e.message);
    }
}

try {
    MyClass.myMethod(3);
} catch(e) {
    if (e.name === "Error3") {
        console.log(e.name);
        console.log(e.message);
    }
}

実行結果

$ node main.js
Error1
Error1 occured.
Error2
Error2 occured.
Error3
Error3 occured.

参考