-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow proper prototype inheritance and subclassing #105
base: master
Are you sure you want to change the base?
Conversation
this will fail below Node 6 bc of use of I think |
this change allows us to throw for createErrors.HttpError() and new createErrors.HttpError(), but not on class Foo extends createErrors.HttpError {}
needs some kind of docs nod to the new capabilities? It changes undocumented features, but can at least update the docs to show an example of subclassing. Needs an update to History as well |
e01a3eb
to
5a4efd9
Compare
I think there is a bunch of good stuff here, but maybe a few many changes at once to get the job done? Also, I am not sure, but other times I have seen |
There's no rush to merge this. It can't right now anyways bc it would be a semver major Node.js version change in it's current form. I am actively experimeting with a variety of approaches which don't require Reflect, and so are back-compat w/o node version bump. In the original version of the code, we set the prototype of the instance explicitly to ClientError.prototype using The issue is repro'd by: const createError = require('http-errors')
class CustomError extends createError.NotFound {}
const err = new CustomError()
console.log(err instanceof CustomError) // false
logProtoChain(err) // NotFound.HttpError.Error We have Factory Functions, not classes, so the proto story is different from what folks expect when using classes. I'll endeavor to explain why Reflect is needed here, this is not complicated JS but it is high cognitive load bc the issue this aims to fix inherently crosses that pre-es6 divide and you have to hold old an new patterns in your head. Currently we dynamically create Factory functions, so its a little unique even for factory functions. |
As this is a major, did you explore leaning in and just using sub classing instead of factory functions? Not sure I immediately have enough context to know if this is a good idea, but seems worth considering to me instead of working hard to fix. Another thing to look at instead of Reflect would be to see if we wanted this in the current major to do it with older style patterns. The |
Converted to a draft as it should've been one to begin with, I don't intend to land this to master currently. It requires a major for Node version requirements of the current PR, and not knowing what the next major would look like it's hard to tell if this would even be needed. Keeping it open though because I think it is worth living as a draft right now to help with understanding of the current package's internals w/r/t object creation @wesleytodd yes I explored that but it is an API breaking change to drop the |
Cool, lets try and get this on the list for things to address with the next major. I absolutely feel like this is a key feature to land. Do we think this should land before v5 of Also, nudge nudge, you should consider signing up to be a captain for this project. |
prior discussion about the way object creation is handled #11 |
closes #98
The Issue
Currently subclasses of error classes like NotFound do not correctly set up the prototype chain, leading to unexpected behavior with instanceof checks. Also, extending HttpError is not possible due to a check that prevents instantiating the abstract class. Additionally,
Extending error classes like
NotFound
do not wire up the prototype properly to be able to checkinsanceof
on it.Extending
HttpError
is not possible currently because of the throw to prevent instantiating the abstract class.The Change
This PR uses
Reflect.construct
when creating errors in the factory functions to properly set prototype to the target when used withnew
, or to the factory function itself when called withoutnew
. These changes ensure that subclasses of the named HTTP error constructors, such asNotFound
, correctly inherit properties and behaviors while maintaining the expected prototype chain.Key Changes:
Reflect.construct
within ClientError and ServerError constructors to dynamically set the prototype based onnew.target
, supporting correct inheritance for subclasses.HttpError
to prevent direct instantiation but allow subclassing, maintaining its intended use as an abstract class and throw behavior when instantiated.Developers can now extend built-in HTTP error constuctors more intuitively, ensuring instances of custom errors are recognized as instances of their specific class as well as their HTTP error ancestors:
HttpError instantiation change:
Resources