You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Consider replacing error factories with real constructors #11
Currently the "constructors" are actually just factory functions and we have a total of three such factories in the code that do pretty much the same thing (ClientError, ServerError and the exported function).
The only reason ServerError and ClientError have any inheritance at all is that the __proto__ property of the new error is manipulated directly. This is incompatible with some possible environments (the double underscores are there for a reason).
It would be nice if the two constructors were actual constructors (i.e. return this, not a retrofitted error). For an example of how this would work see httperr@0.5.0.
The obvious drawback is that Object.prototype.toString returns [object Object] instead of [object Error] and util.isError returns false (though instanceof checks pass as one would expect). The benefit is that this approach can be made to work in environments that don't support overriding __proto__.
The obvious drawback is that Object.prototype.toString returns [object Object] instead of [object Error] and util.isError returns false (though instanceof checks pass as one would expect).
Breaking this is not acceptable, so we'd only consider solutions that do not break that functionality, but I'm all-ears on solutions as long as Object.prototype.toString(err) === '[object Error]'.
Object.prototype.toString gets the name from the internal [[Class]] property of an object (specified in ECMA-262. There is no way to alter it, which is why you can't actually inherit correctly from Error objects in JS.
So it's basically a question of being compatible with util.isError/Object.prototype.toString vs being compatible with environments that don't support __proto__ assignment. Not great, but such is life.
Unless someone has a brilliant idea, feel free to close this issue then.
Nope, that wouldn't pass instanceof checks. You need to manipulate the [[Prototype]] for that and if you don't use a real constructor you can only do that via __proto__.
Also, new is redundant in that case. It just creates a new instance of NotFoundError and immediately discards it because the "constructor" returns a value.
Gotcha. I mean, Error.captureStackTrace is just as unofficial as __proto__, so getting rid of one under that premise means getting rid of both. If Object.setPrototypeOf was adopted faster, then that would be a __proto__ alternative, but alas it's not.
Wow, this has been open for a long time :) So as you may have seen, I just closed it with a commit. The commit doesn't exactly correlate with the title of the issue, but I feel like it correlates a bit with the ideas floating around to the underlying issue, which was using __proto__ in order to get a proper [[Class]] on the object.
The commit replaces using __proto__ with the setprototypeof module, which simply uses the standardized Object.setProtototypeOf function, falls back to using __proto__ if possible, otherwise will just copy the properties as a last resort. I think this should cover the compatibility bases.
No problem :) I'm trying to match through here and pick up all these things that just kind of fell off, haha. Hopefully everything will start to get closed now. If you do have any new or additional comments, always feel free to open an issue!
I noticed the docs don't mention using the named error constructors directly (i.e. new NotFound()). Is there a reason why? also since they are factories it seems that throw NotFound would be the call but ESLint balks at the capitalization. Is the future going to using these as legit constructors or heading towards a camelCase factory var?
Activity
dougwilson commentedon Oct 28, 2014
Breaking this is not acceptable, so we'd only consider solutions that do not break that functionality, but I'm all-ears on solutions as long as
Object.prototype.toString(err) === '[object Error]'.pluma commentedon Oct 28, 2014
I have no idea how
Object.prototype.toStringdecides this, actually, and can't find anything on MDN either. If you have any idea, shoot :)dougwilson commentedon Oct 28, 2014
Object.prototype.toStringgets the name from the internal[[Class]]property of an object (specified in ECMA-262. There is no way to alter it, which is why you can't actually inherit correctly fromErrorobjects in JS.pluma commentedon Oct 28, 2014
So it's basically a question of being compatible with
util.isError/Object.prototype.toStringvs being compatible with environments that don't support__proto__assignment. Not great, but such is life.Unless someone has a brilliant idea, feel free to close this issue then.
dougwilson commentedon Oct 28, 2014
You can support both with (this is just a simplified example):
pluma commentedon Oct 28, 2014
Nope, that wouldn't pass
instanceofchecks. You need to manipulate the[[Prototype]]for that and if you don't use a real constructor you can only do that via__proto__.Also,
newis redundant in that case. It just creates a new instance ofNotFoundErrorand immediately discards it because the "constructor" returns a value.dougwilson commentedon Oct 28, 2014
Gotcha. I mean,
Error.captureStackTraceis just as unofficial as__proto__, so getting rid of one under that premise means getting rid of both. IfObject.setPrototypeOfwas adopted faster, then that would be a__proto__alternative, but alas it's not.dougwilson commentedon Oct 28, 2014
P.S. I hoped on IRC since you seem to be active :)
pluma commentedon Oct 29, 2014
I'm on #jshttp. We could use gitter if you want to keep public logs, btw. It also supports Markdown unlike IRC ;)
dougwilson commentedon May 18, 2016
Wow, this has been open for a long time :) So as you may have seen, I just closed it with a commit. The commit doesn't exactly correlate with the title of the issue, but I feel like it correlates a bit with the ideas floating around to the underlying issue, which was using
__proto__in order to get a proper[[Class]]on the object.The commit replaces using
__proto__with thesetprototypeofmodule, which simply uses the standardizedObject.setProtototypeOffunction, falls back to using__proto__if possible, otherwise will just copy the properties as a last resort. I think this should cover the compatibility bases.pluma commentedon May 18, 2016
Thanks @dougwilson. I appreciate the effort you're putting into these projects. I think the change is in spirit with this issue.
dougwilson commentedon May 18, 2016
No problem :) I'm trying to match through here and pick up all these things that just kind of fell off, haha. Hopefully everything will start to get closed now. If you do have any new or additional comments, always feel free to open an issue!
cyberwombat commentedon Nov 6, 2018
I noticed the docs don't mention using the named error constructors directly (i.e. new NotFound()). Is there a reason why? also since they are factories it seems that
throw NotFoundwould be the call but ESLint balks at the capitalization. Is the future going to using these as legit constructors or heading towards a camelCase factory var?dougwilson commentedon Nov 6, 2018
The docs for using the constructor is here: https://github.com/jshttp/http-errors/blob/master/README.md#new-createerrorcode--namemsg
dougwilson commentedon Nov 6, 2018
Please open a new issue if you're having issues or need help instead of a 2 year closed issue.