http-errors icon indicating copy to clipboard operation
http-errors copied to clipboard

Allow HttpError extension by ES6 classes

Open nathanlepori opened this issue 2 years ago • 2 comments

To allow better interoperability with ES6 classes (which are forced to call the super() constructor) it is better to add the following condition to the HttpError constructor:

if (this.constructor === HttpError) {
    throw new TypeError('cannot construct abstract class')
}

This way the class can be extended with a concrete class like this:

class MyHttpError extends HttpError {
    constructor() {
        super();
        ...
    }
}

A variant using ES6 classes as base class is shown here but the same works with old school constructor functions as well.

nathanlepori avatar Jun 21 '23 11:06 nathanlepori

moving this comment and repro from another issue #101 :

https://github.com/jshttp/http-errors/issues/101#issue-1958051775

I was surprised I couldn't subclass errors. I would have expected my ValidationError class would support an instanceof check against itself.

const { BadRequest } = require('http-errors')
const assert = require('assert')


class ValidationError extends BadRequest {}

const err = new ValidationError()
console.log(err.name)
// "BadRequestError"

// err should be an instance of ValidationError
assert(err instanceof ValidationError)

https://runkit.com/cdignam-segment/6536e492c20c690008824a73

jonchurch avatar Mar 08 '24 19:03 jonchurch

There's two different concepts in this issue.

Extending HttpError is not possible currently because of the throw to prevent instantiating the abstract class.

const createErrors = require('http-errors')

class NewBase extends createErrors.HttpError // this will throw a type error

Extending error classes like NotFound do not wire up the prototype properly to be able to check insanceof on it.

const createErrors = require('http-errors')

class ValidationError extends createErrors.BadRequest {}

assert(err instanceof ValidationError) // false

jonchurch avatar Mar 09 '24 04:03 jonchurch