2 min read

NO_INSTANCEOF_ERROR

Disallows using `error instanceof Error` comparisons due to risk of false negatives.
Table of Contents

Conformance is available on Enterprise plans

This rule is available from version 1.5.0.

A common pattern for checking if an object is an error is to use error instanceof Error.

This pattern is problematic because errors can come from other realms. Errors from other realms are instantiated from the realm's global Error constructor, and are therefore not instances of the current realm's global Error constructor and will not pass the instanceof check.

Some examples of where you might hit this include:

  • In Node.js, errors from a workers are instances of Error from the worker's global environment.
  • In browser environments, errors from iframe are instances of Error from the iframe's global environment (i.e. iframe.contentWindow.Error).

By default, this rule is disabled. To enable it, refer to customizing Conformance.

In this example, an error is returned from a vm context. As this error was created in a different realm, instanceof Error returns false.

const vm = require('node:vm');
 
const context = vm.createContext({});
const error = vm.runInContext('new Error()', context);
 
if (error instanceof Error) {
  // Returns `false` because `error` is from a different realm.
}

You can use isNativeError in Node.js environments, which will return true for errors from other realms.

import { isNativeError } from 'node:util/types';
const vm = require('node:vm');
 
const context = vm.createContext({});
const error = vm.runInContext('new Error()', context);
 
if (isNativeError(error)) {
  // ...
}

Use a library like is-error to ensure you cover errors from other realms.

You can also use Object.prototype.toString.call(error) === '[object Error]' in some cases. This method will not work for custom errors, and you'll need to traverse the prototype chain (i.e. Object.getPrototypeOf(error))to handle those cases.

The following code is a simplified version of the code used in the is-error library:

function isError(error) {
  if (typeof error !== 'object') {
    return false;
  }
 
  if (error instanceof Error) {
    return true;
  }
 
  let currentError = error;
  while (currentError) {
    if (Object.prototype.toString.call(currentError) === '[object Error]') {
      return true;
    }
    currentError = Object.getPrototypeOf(currentError);
  }
 
  return false;
}
Last updated on May 23, 2024