エラーの種類を整理する(TypeError・ReferenceError・SyntaxError) - JavaScript

JavaScript には用途別にいくつかのエラー型が用意されています。エラーの種類を理解しておくと、バグの原因特定が早くなり、適切なエラーハンドリングができるようになります。

主要なエラー型一覧

エラー型発生する状況
TypeError型が不正なとき
ReferenceError未定義の変数を参照したとき
SyntaxError構文が間違っているとき
RangeError値が有効範囲外のとき
URIErrorURI 関数の引数が不正なとき
EvalErroreval 関数に関するエラー(現在はほぼ使われない)

TypeError

最も遭遇する機会が多いエラーです。null や undefined に対してメソッドを呼び出したり、関数でないものを関数として呼び出したりすると発生します。

// null のプロパティにアクセス
const obj = null;
obj.name; // TypeError: Cannot read properties of null

// 関数でないものを呼び出す
const num = 42;
num(); // TypeError: num is not a function

// 書き込み禁止プロパティへの代入
const frozen = Object.freeze({ x: 1 });
frozen.x = 2; // TypeError(strict mode)

ReferenceError

宣言されていない変数を参照しようとすると発生します。タイプミスでよく起きるエラーです。

console.log(undeclaredVariable);
// ReferenceError: undeclaredVariable is not defined

// let/const の一時的デッドゾーン
console.log(x); // ReferenceError
let x = 10;

var と違い、let や const は宣言前に参照するとエラーになります。

SyntaxError

コードの構文が間違っているときに発生します。このエラーはコードの解析段階で検出されるため、try-catch では捕捉できません。

// 括弧の閉じ忘れ
const arr = [1, 2, 3;
// SyntaxError: Unexpected token ';'

// JSON.parse での構文エラー(これは捕捉可能)
try {
  JSON.parse('{invalid}');
} catch (error) {
  console.log(error.name); // "SyntaxError"
}

JSON.parse など、実行時に文字列を解析する場合の SyntaxError は try-catch で捕捉できます。

RangeError

値が許容範囲を超えているときに発生します。

// 配列の長さに負の値
const arr = new Array(-1);
// RangeError: Invalid array length

// 無限再帰
function infinite() {
  infinite();
}
infinite();
// RangeError: Maximum call stack size exceeded

// toFixed の引数が範囲外
(1.5).toFixed(200);
// RangeError: toFixed() digits argument must be between 0 and 100

URIError

encodeURI や decodeURI などの URI 関連関数で、不正な引数が渡されたときに発生します。

decodeURIComponent('%');
// URIError: URI malformed

decodeURI('%E0%A4%A');
// URIError: URI malformed

エラー型による分岐処理

instanceof を使って、エラーの種類に応じた処理を行えます。

try {
  riskyOperation();
} catch (error) {
  if (error instanceof TypeError) {
    console.log('型に関するエラーです');
  } else if (error instanceof ReferenceError) {
    console.log('未定義の変数を参照しています');
  } else if (error instanceof SyntaxError) {
    console.log('構文エラーです');
  } else {
    console.log('その他のエラー:', error.message);
  }
}

エラー型の継承関係

すべての組み込みエラーは Error を継承しています。

const typeError = new TypeError('型が違います');
console.log(typeError instanceof TypeError); // true
console.log(typeError instanceof Error);     // true

そのため、どのエラーも name, message, stack といった共通のプロパティを持っています。