0

Getting familiar with ES6 classes and came across some unexpected behaviour while trying to create custom errors (i.e. extending Error).

Below is the module (error.js) code:

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

exports.BadRequestError = BadRequestError;

Then when I use it as follows in node console, you can see I get false when I check if err instanceof Error...

The rest of the extension seems to be fine; I can check .name, .message, .stack etc. without issues.

> var error = require("./error");
undefined
> var err = new error.BadRequestError("This is a bad request");
undefined
> err.name
'BadRequestError'
> err.message
'This is a bad request'
> err.stack
'BadRequestError: This is a bad request\n    at BadRequestError (C:\<hidden>\error.js:3:5)\n    at repl:1:11\n    at sigintHandlersWrap (vm.js:32:31)\n    at sigintHandlersWrap (vm.js:96:12)\n    at ContextifyScript.Script.runInContext (vm.js:31:12)\n    at REPLServer.defaultEval (repl.js:308:29)\n    at bound (domain.js:280:14)\n    at REPLServer.runBound [as eval] (domain.js:293:12)\n    at REPLServer.<anonymous> (repl.js:489:10)\n    at emitOne (events.js:101:20)'
> err instanceof Error
false
> err instanceof error.BadRequestError
true

I would expect this to return true, but oddly it isn't. Is this correct behaviour or am I missing something? Any help/explanations would be greatly appreciated.

Mitch
  • 291
  • 2
  • 17
  • I wouldn't be surprised that this isn't working (yet) for built-in classes / functions. You have to consider that until now it wasn't really possible to reliably extend native classes / constructors. ES6 formalizes this, but that doesn't mean that it is properly supported yet. – Felix Kling Aug 03 '16 at 15:19
  • 3
    it works for me in the chrome console. Could be just a Node issue. – nem035 Aug 03 '16 at 15:20
  • You typically [cannot extend errors](http://stackoverflow.com/questions/30402287/extended-errors-do-not-have-message-or-stack-trace). – ssube Aug 03 '16 at 15:25
  • That's the thing though, .name, .message and .stack are all there and working as expected. I'll update the post with the additional info. – Mitch Aug 03 '16 at 15:29
  • Are you doing this directly in ES6 without any transpilation (like babel)? – evolutionxbox Aug 03 '16 at 15:33
  • No transpiling. Calling it directly from node console using the latest version of node. – Mitch Aug 03 '16 at 15:34
  • @ssube: That's a limitation of Babel, not JavaScript itself. – Felix Kling Aug 03 '16 at 15:34
  • @FelixKling I'm under the impression that it's an engine thing, not language or transpiler. The browsers had to support subclassing the built in types, and before they did, we had to work around it by creating fake subclasses. – ssube Aug 03 '16 at 15:43
  • @Felix Kling Based on [this](http://node.green/), class and extend should be fully supported all the way back to v5.11. – Mitch Aug 03 '16 at 15:45
  • Works for me in 6.2.1 `> new BadRequestError() instanceof Error true ` – Yury Tarabanko Aug 03 '16 at 16:02
  • @Yury What did you do differently? I'm trying it in v6.3 and still getting false – Mitch Aug 04 '16 at 08:05
  • I'm not creating a separate file that's it. [ProofPic](http://i.stack.imgur.com/2mOh1.png) – Yury Tarabanko Aug 04 '16 at 10:03
  • Here is online demo using tonicdev https://tonicdev.com/tarabyte/subclassing-error – Yury Tarabanko Aug 04 '16 at 10:11
  • 1
    Yep, I can confirm that it works fine when I declare the class in the console. But doesn't work when I require in the error.js script. The structure of the two is the exact same but somehow the fact the class is in another script seems to break instanceof. Does anyone have an explanation for this? – Mitch Aug 04 '16 at 12:55

0 Answers0