search

Home  >  Q&A  >  body text

Extended Error Class - TypeScript

I tried to throw a custom error and print my "CustomError" class name in the console instead of "Error", but with no success:

class CustomError extends Error { 
    constructor(message: string) {
      super(`Lorem "${message}" ipsum dolor.`);
      this.name = 'CustomError';
    }
}
throw new CustomError('foo');

The output is Uncaught Error: Load "foo" very pain.

What I expected: Uncaught CustomError: Lorem "foo" ipsum dolor.

I was wondering if it could be done using just TS (without messing with JS prototypes)?

P粉311563823P粉311563823405 days ago500

reply all(2)I'll reply

  • P粉659516906

    P粉6595169062023-10-17 19:52:38

    The problem is that when you call super and the new object does not have the expected prototype chain, i.e. it is an instance of Error, not an instance of CustomError .

    This problem can be solved elegantly using 'new.target', which is supported since Typescript 2.2, see here: https://www.typescriptlang.org/docs/handbook/release-notes/ typescript-2-2.html

    class CustomError extends Error {
      constructor(message?: string) {
        // 'Error' breaks prototype chain here
        super(message); 
    
        // restore prototype chain   
        const actualProto = new.target.prototype;
    
        if (Object.setPrototypeOf) { Object.setPrototypeOf(this, actualProto); } 
        else { this.__proto__ = actualProto; } 
      }
    }

    The advantage of using new.target is that you don't have to hardcode the prototype, like some of the other answers asked here. This has the further advantage that classes inheriting from CustomError will also automatically get the correct prototype chain.

    If you were to hardcode the prototype (e.g. Object.setPrototype(this, CustomError.prototype)), CustomError itself would have a working prototype chain, but any class from CustomError inheritance will be broken, e.g. instances of class VeryCustomError < CustomError< CustomError will not be the expected instanceof VeryCustomError, but just instanceof CustomError .

    See also: https://github.com/Microsoft/TypeScript/issues /13965#issuecomment-278570200

    reply
    0
  • P粉949848849

    P粉9498488492023-10-17 16:00:03

    Are you using typescript version 2.1 and converting to ES5? Check this section of the breaking changes page for possible issues and workarounds: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built -ins-like -error-array-and-map-may-no-longer-work

    Relevant bits:

    reply
    0
  • Cancelreply