Extending Error in Javascript with ES6 syntax & Babel

后端 未结 14 1759
你的背包
你的背包 2020-11-28 01:28

I am trying to extend Error with ES6 and Babel. It isn\'t working out.

class MyError extends Error {
  constructor(m) {
    super(m);
  }
}

var error = new          


        
相关标签:
14条回答
  • 2020-11-28 01:57

    This works for me:

    /**
     * @class AuthorizationError
     * @extends {Error}
     */
    export class AuthorizationError extends Error {
        message = 'UNAUTHORIZED';
        name = 'AuthorizationError';
    }
    
    0 讨论(0)
  • 2020-11-28 01:58

    Based on Karel Bílek's answer, I'd make a small change to the constructor:

    class ExtendableError extends Error {
      constructor(message) {
        super(message);
        this.name = this.constructor.name;
        if (typeof Error.captureStackTrace === 'function') {
          Error.captureStackTrace(this, this.constructor);
        } else { 
          this.stack = (new Error(message)).stack; 
        }
      }
    }    
    
    // now I can extend
    
    class MyError extends ExtendableError {}
    
    var myerror = new MyError("ll");
    console.log(myerror.message);
    console.log(myerror instanceof Error);
    console.log(myerror.name);
    console.log(myerror.stack);
    

    This will print MyError in the stack, and not the generic Error.

    It will also add the error message to the stack trace - which was missing from Karel's example.

    It will also use captureStackTrace if it's available.

    With Babel 6, you need transform-builtin-extend (npm) for this to work.

    0 讨论(0)
  • 2020-11-28 01:58

    Quoting

    class MyError extends Error {
      constructor(message) {
        super(message);
        this.message = message;
        this.name = 'MyError';
      }
    }
    

    There is no need for this.stack = (new Error()).stack; trick thanks to super() call.

    Although the above codes cannot output the stack trace unless this.stack = (new Error()).stack; or Error.captureStackTrace(this, this.constructor.name); is invoked in Babel. IMO, it maybe one issue in here.

    Actually, the stack trace can be output under Chrome console and Node.js v4.2.1 with this code snippets.

    class MyError extends Error{
            constructor(msg) {
                    super(msg);
                    this.message = msg;
                    this.name = 'MyError';
            }
    };
    
    var myerr = new MyError("test");
    console.log(myerr.stack);
    console.log(myerr);
    

    Output of Chrome console.

    MyError: test
        at MyError (<anonymous>:3:28)
        at <anonymous>:12:19
        at Object.InjectedScript._evaluateOn (<anonymous>:875:140)
        at Object.InjectedScript._evaluateAndWrap (<anonymous>:808:34)
        at Object.InjectedScript.evaluate (<anonymous>:664:21)
    

    Output of Node.js

    MyError: test
        at MyError (/home/bsadmin/test/test.js:5:8)
        at Object.<anonymous> (/home/bsadmin/test/test.js:11:13)
        at Module._compile (module.js:435:26)
        at Object.Module._extensions..js (module.js:442:10)
        at Module.load (module.js:356:32)
        at Function.Module._load (module.js:311:12)
        at Function.Module.runMain (module.js:467:10)
        at startup (node.js:134:18)
        at node.js:961:3
    
    0 讨论(0)
  • 2020-11-28 02:00

    Not using Babel, but in plain ES6, the following seems to work fine for me:

    class CustomError extends Error {
        constructor(...args) {
            super(...args);
            this.name = this.constructor.name;
        }
    }
    

    Testing from REPL:

    > const ce = new CustomError('foobar');
    > ce.name
    'CustomError'
    > ce.message
    'foobar'
    > ce instanceof CustomError
    true
    > ce.stack
    'CustomError: foobar\n    at CustomError (repl:3:1)\n ...'
    

    As you can see, the stack contains both the error name and message. I'm not sure if I'm missing something, but all the other answers seem to over-complicate things.

    0 讨论(0)
  • 2020-11-28 02:02

    I am trying to extend Error with ES6

    That class MyError extends Error {…} syntax is correct.

    Notice that transpilers still do have problems with inheriting from builtin objects. In your case,

    var err = super(m);
    Object.assign(this, err);
    

    seems to fix the problem.

    0 讨论(0)
  • 2020-11-28 02:03

    Edit: Breaking changes in Typescript 2.1

    Extending built-ins like Error, Array, and Map may no longer work.

    As a recommendation, you can manually adjust the prototype immediately after any super(...) calls.

    Editing Lee Benson original answer a little bit works for me. This also adds stack and additional methods of ExtendableError class to the instance.

    class ExtendableError extends Error {
       constructor(message) {
           super(message);
           Object.setPrototypeOf(this, ExtendableError.prototype);
           this.name = this.constructor.name;
       }
       
       dump() {
           return { message: this.message, stack: this.stack }
       }
     }    
    
    class MyError extends ExtendableError {
        constructor(message) {
            super(message);
            Object.setPrototypeOf(this, MyError.prototype);
        }
    }
    
    var myerror = new MyError("ll");
    console.log(myerror.message);
    console.log(myerror.dump());
    console.log(myerror instanceof Error);
    console.log(myerror.name);
    console.log(myerror.stack);
    
    0 讨论(0)
提交回复
热议问题