skip to Main Content

I have an app in node.js with typescript and express.js, compiled with ts-node in node v18.14.0 and trying to handle the errors I ran into this problem and I can’t quite understand why it happens and how to get to the expected result.

class CustomError extends Error {
  constructor(message?: string) {
    super(message);
  }
}

const err = new CustomError('unauth');

console.log(err instanceof CustomError); // false in node.js

I don’t understand why it returns ‘true’ in a react app with vite.js (as expected) and ‘false’ in a node.js app. And how can I check if the ‘err’ object was created with the ‘CustomError’ class?

2

Answers


  1. In case of es5 output, it will not work but I believe changing output will change lot’s of thing. What you can do here is to override the name property like this:

    class CustomError extends Error {
      name = "CustomError";
      constructor(message?: string) {
        super(message);
      }
    }
    
    const err = new CustomError('unauth');
    
    console.log(err.name === "CustomError");
    

    For better code maintainability, you should use constant to store the name error like this:

    const CUSTOM_ERROR = "CustomError"
    class CustomError extends Error {
      name = CUSTOM_ERROR;
      constructor(message?: string) {
        super(message);
      }
    }
    
    const err = new CustomError('unauth');
    
    console.log(err.name === CUSTOM_ERROR);
    
    Login or Signup to reply.
  2. This issue is extensively covered in this GitHub issue and covered in the TypeScript 2.1 breaking changes. In short, you shouldn’t try to extend built-in classes when using any transpiler that emits ES5 code. This includes non-TypeScript transpilers like Babel too.

    The easiest solution is to just not compile to ES5. The difference between your browser and node.js code is probably that the browser transpilation was outputting ES6 while your node.js one was using ES5 for some reason. If you actually need to support ES5, then the breaking change note linked above has a solution: manually use Object.setPrototypeOf() inside the constructor to set this‘s prototype to itself:

    class CustomError extends Error {
      constructor(message?: string) {
        super(message);
        Object.setPrototypeOf(this, CustomError.prototype);
      }
    }
    
    const err = new CustomError('unauth');
    console.log(err instanceof CustomError); // => true
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search