Error インスタンスかどうか判定する Error.isError() メソッド
Error.isError() メソッドは、オブジェクトが Error インスタンスかどうかを判定するためのメソッドです。今までも instanceof 演算子を使用して判定することができましたが、偽陽性と偽陰性が発生する可能性があります。Error.isError() メソッドは Array.isArray() と同じく内部スロットを使用して判定するため、より堅牢に判定することができます。
Error.isError() メソッドは、オブジェクトが Error インスタンスかどうかを判定するためのメソッドです。渡された値が Error インスタンスであれば true を、そうでなければ false を返します。
const error = new Error("An error occurred");
console.log(Error.isError(error)); // true
console.log(Error.isError({})); // false
console.log(Error.isError(3)); // false
console.log(Error.isError(null)); // falseError.isError() メソッドの使い方
Error.isError() メソッドの使い道として真っ先に思いつくのは、try-catch 構文でキャッチしたエラーが Error インスタンスかどうかを判定することです。TypeScript では catch 節でキャッチしたエラーの型は unknown 型になります。これは JavaScript はどのような型の値でも例外としてスローできるためです。
適切なエラー処理を行うためには、キャッチしたエラーが Error インスタンスであるかどうかを判定する必要があります。Error.isError() メソッドを使用することで、簡単に判定できます。
try {
// 何らかの処理
} catch (error) {
if (Error.isError(error)) {
console.error(error.message);
} else {
console.error("Unknown error:", error);
}
}とはいえ、この用途であれば Error.isError() メソッドを使用しなくても、instanceof 演算子を使用して判定することもできます。
try {
// 何らかの処理
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
} else {
console.error("Unknown error:", error);
}
}しかし、instanceof 演算子を使用した判定では偽陽性と偽陰性が発生する可能性があります。たとえば、以下のように __proto__ プロパティを無理やり上書きしてしまえば、本物の Error インスタンスでない場合でも instanceof 演算子は true を返してしまいます。
const error = new Error("An error occurred");
const fakeError = {
message: "Fake error",
__proto__: Error.prototype,
};
console.log(error instanceof Error); // true
console.log(fakeError instanceof Error); // trueError.isError() メソッドを使用するとプロトタイプチェーン内で Error であったとしても Error インスタンスでない場合は false を返します。これにより、偽陽性を防ぐことができます。
const error = new Error("An error occurred");
const fakeError = {
message: "Fake error",
__proto__: Error.prototype,
};
console.log(Error.isError(error)); // true
console.log(Error.isError(fakeError)); // falseこの挙動は Array.isArray() と同じ仕組みによって実現されています。Array.isArray() や Error.isError() メソッドは偽装不可能な内部スロット([[Internal Slot]])を直接チェックして真偽値を返します。このような内部スロットの有無の確認は「ブランドチェック」と呼ばれています。
cross-realm 環境での使用
Error.isError() メソッドは cross-realm 環境で偽陽性を防ぐために使用できます。たとえば、iframe や Web Worker などの異なる実行環境で Error インスタンスを作成した場合、instanceof 演算子は常に false を返します。
Error.isError() メソッドを使用することで、異なる実行環境で作成された Error インスタンスでも正しく判定できます。
const iframe = document.createElement("iframe");
document.body.appendChild(iframe);
const iframeError = iframe.contentWindow?.Error;
const error = new iframeError("An error occurred");
console.log(error instanceof Error); // false
console.log(error instanceof iframeError); // true
console.log(Error.isError(error)); // trueまとめ
Error.isError()メソッドは、オブジェクトがErrorインスタンスかどうかを判定するためのメソッドinstanceof演算子を使用した Error インスタンスの判定では偽陽性と偽陰性が発生する可能性があるError.isError()メソッドはArray.isArray()と同じく内部スロットを使用して判定するため、偽陽性や偽陰性を防ぐことができる- cross-realm 環境で作成された
Errorインスタンスでも正しく判定できる
