Patrick J. S. Patrick J. S. - 2 months ago 7
Node.js Question

Is there a way in es6 to inherit from Error and not have the constructor in the stacktrace?

I tried to write a

HTTPError
class by extending Error:

class HTTPError extends Error {
constructor(codeArg, message){
let code = codeArg || 500;
super(message || http.STATUS_CODES[code]); // first line in stack trace
this.code = code;
}
}


This works mostly fine, but when I
throw
such an error, the line where
super
is called, is the first line in the stack trace (assuming nodejs):

> const HTTPError = require('./HTTPError')
undefined
> let e = new HTTPError(418)
undefined
> throw e
Error: I'm a teapot
at HTTPError (/home/pat/Scripts/js/HTTPError.js:6:6)
at repl:1:9
at sigintHandlersWrap (vm.js:32:31)
at sigintHandlersWrap (vm.js:96:12)
at ContextifyScript.Script.runInContext (vm.js:31:12)
at REPLServer.defaultEval (repl.js:308:29)
at bound (domain.js:280:14)
at REPLServer.runBound [as eval] (domain.js:293:12)
at REPLServer.<anonymous> (repl.js:489:10)
at emitOne (events.js:101:20)
> e.code
418


The first line of the stack trace is in the constructor of
HTTPError
. The interesting one (the one where it was created) is the second
repl:1:9
line. Is there a way around this?

Answer

Error.captureStackTrace should be able to fix this, though it's not standard ES6.

class HTTPError extends Error {
   constructor(codeArg, message){
      let code = codeArg || 500;
      super(message || http.STATUS_CODES[code]);
      Error.captureStackTrace(this, new.target);
      this.code = code;
   }
}

Ultimately I'd call it a bug in the Error constructor though, this should not be necessary. There's no standard for stack traces yet, so this is completely implementation-dependent behaviour.

Comments