[Question] ES6 class extensions
abrenneke opened this issue · 4 comments
Hey this library looks really interesting! We kind of thought it was funny for a package called modern-errors
to not use class SomeError extends BaseError
, what's the rationale for the .subclass
method instead? Less boilerplate to override the constructor?
Hi Andy,
This is a great question!
Direct subclassing was actually how this library was initially designed. However, I had to use a factory method (.subclass()
) instead for the following reason: this library requires some logic to be performed when an error class is being created.
For example, when an error class is created, some validation logic is performed to ensure it is valid and safe to use. It is important for such validation to fail as soon as the error class is created (which is typically at load time), as opposed to waiting for an error instance to be created (which is typically at runtime), since failing "hard" and early prevents situations where your error handling ends up failing itself, which is hard to debug.
Some additional logic performed when an error class is created also includes: properly setting ErrorClass.prototype.name
.
Unfortunately, there is no convenient way to perform some logic when a class is being inherited (as opposed to when it is first instantiated). The simplest solution would be to require users to manually call some ErrorClass.init()
after declaring each class. However, I found it to be slightly more complex than the current solution. Decorators could also be a solution, but they are still an experimental JavaScript feature.
Side note: when using the custom
option, subclassing is in fact used. Also, ErrorClass.subclass()
can be used to make some of your error classes inherit from others.
I hope this clears up the rationale behind this! :)
Thanks for the detailed explanation @ehmicky!
Yeah sounds like a roughly appropriate use of decorators (finally stage 3 at least and finally getting into TS) but they'd have to go on the derived classes something like
import { error, BaseError } from 'modern-errors';
export @error class DerivedError extends BaseError {}
which is still a bit awkward.
Absolutely!
@all-contributors Could you please add @abrenneke for ideas and question?
I've put up a pull request to add @abrenneke! 🎉