rtfeldman / seamless-immutable

Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.
BSD 3-Clause "New" or "Revised" License
5.37k stars 194 forks source link

ImmutableError returns a Error that dose not extend Error #143

Closed hzrd149 closed 7 years ago

hzrd149 commented 8 years ago

the code here is setting the __proto__ of the error to the constructor function of ImmutableError

which means that

var err = new ImmutableError('a test err');
err instanceof Function == true;
err instanceof Object == true;
err instanceof Error == false;
typeof err == 'object';

also since it extends a function and technically is not an Error, it causes jasmine to crash

i would suggest doing something like this

err.__proto__ = ImmutableError.prototype;

anyways if you guys could fix this that would be great. thanks.

holyjak commented 7 years ago

It also causes Babel to fail:

$ babel-node
> var Immutable = require("seamless-immutable");
> (new Immutable.ImmutableError("xxxx")).stack
TypeError: Function.prototype.toString is not generic
    at Function.toString (native)
    at Function.toString (/Users/me/Work/project/node_modules/babel/node_modules/babel-core/node_modules/core-js/modules/$.redefine.js:26:62)
    at Function.prepareStackTrace (/Users/me/Work/project/node_modules/babel/node_modules/babel-core/node_modules/source-map-support/source-map-support.js:303:16)
    at repl:3:37
    at Object.exports.runInThisContext (vm.js:54:17)
    at _eval (/Users/me/Work/project/node_modules/babel/lib/_babel-node.js:86:26)

A standard error works without a problem: ```

(new Error("xxx")).stack 'Error: xxx\n at repl:3:1\n at Object.exports.runInThisContext (vm.js:54:17)\n at _eval (/Users/me/Work/project/node_modules/babel/lib/_babel-node.js:86:26)\n at REPLServer.replEval (/Users/me/Work/project/node_modules/babel/lib/_babel-node.js:169:14)\n at bound (domain.js:280:14)\n at REPLServer.runBound as eval\n at REPLServer. (repl.js:393:12)\n at emitOne (events.js:77:13)\n at REPLServer.emit (events.js:169:7)\n at REPLServer.Interface._onLine (readline.js:210:10)'```

To troubleshoot the actual exception, you can temporarily do something like this (ES6):

Error.prepareStackTrace = function(error, stack) {
    return stack.map(frame => `${frame.getTypeName() || ''}.${frame.getFunctionName() || "<anonymous fn>"} at ${frame.getFileName()}:${frame.getLineNumber()}`).join("\n");
};
holyjak commented 7 years ago

Fixing for Node: Couldn't we just do

var util = undefined;
try { util = require("util"); } catch () {}
...
if (util) {
  util.inherits(Immutable, Error);
} else {
  ImmutableError.prototype = Error.prototype; // + do something to fix it in the browser if necessary
}