diff --git a/index.js b/index.js index c425f1e..d66f2e4 100644 --- a/index.js +++ b/index.js @@ -13,22 +13,30 @@ */ var deprecate = require('depd')('http-errors') -var setPrototypeOf = require('setprototypeof') var statuses = require('statuses') -var inherits = require('inherits') var toIdentifier = require('toidentifier') +class HttpError extends Error { + constructor (status, message) { + if (new.target === HttpError) { + throw new TypeError('cannot construct abstract class') + } + super(message) + this.status = this.statusCode = status + } +} + /** * Module exports. * @public */ module.exports = createError -module.exports.HttpError = createHttpErrorConstructor() -module.exports.isHttpError = createIsHttpErrorFunction(module.exports.HttpError) +module.exports.HttpError = HttpError +module.exports.isHttpError = createIsHttpErrorFunction(HttpError) // Populate exports for all constructors -populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError) +populateConstructorExports(module.exports, statuses.codes, HttpError) /** * Get the code class of a status code. @@ -86,7 +94,6 @@ function createError () { err = HttpError ? new HttpError(msg) : new Error(msg || statuses.message[status]) - Error.captureStackTrace(err, createError) } if (!HttpError || !(err instanceof HttpError) || err.status !== status) { @@ -104,21 +111,6 @@ function createError () { return err } -/** - * Create HTTP error abstract base class. - * @private - */ - -function createHttpErrorConstructor () { - function HttpError () { - throw new TypeError('cannot construct abstract class') - } - - inherits(HttpError, Error) - - return HttpError -} - /** * Create a constructor for a client error. * @private @@ -127,39 +119,16 @@ function createHttpErrorConstructor () { function createClientErrorConstructor (HttpError, name, code) { var className = toClassName(name) - function ClientError (message) { - // create the error object - var msg = message != null ? message : statuses.message[code] - var err = new Error(msg) - - // capture a stack trace to the construction point - Error.captureStackTrace(err, ClientError) - - // adjust the [[Prototype]] - setPrototypeOf(err, ClientError.prototype) - - // redefine the error message - Object.defineProperty(err, 'message', { - enumerable: true, - configurable: true, - value: msg, - writable: true - }) - - // redefine the error name - Object.defineProperty(err, 'name', { - enumerable: false, - configurable: true, - value: className, - writable: true - }) - - return err + class ClientError extends HttpError { + constructor (message) { + const msg = message != null ? message : statuses.message[code] + super(code, msg) + } } - inherits(ClientError, HttpError) nameFunc(ClientError, className) + ClientError.prototype.name = className ClientError.prototype.status = code ClientError.prototype.statusCode = code ClientError.prototype.expose = true @@ -196,39 +165,16 @@ function createIsHttpErrorFunction (HttpError) { function createServerErrorConstructor (HttpError, name, code) { var className = toClassName(name) - function ServerError (message) { - // create the error object - var msg = message != null ? message : statuses.message[code] - var err = new Error(msg) - - // capture a stack trace to the construction point - Error.captureStackTrace(err, ServerError) - - // adjust the [[Prototype]] - setPrototypeOf(err, ServerError.prototype) - - // redefine the error message - Object.defineProperty(err, 'message', { - enumerable: true, - configurable: true, - value: msg, - writable: true - }) - - // redefine the error name - Object.defineProperty(err, 'name', { - enumerable: false, - configurable: true, - value: className, - writable: true - }) - - return err + class ServerError extends HttpError { + constructor (message) { + var msg = message != null ? message : statuses.message[code] + super(code, msg) + } } - inherits(ServerError, HttpError) nameFunc(ServerError, className) + ServerError.prototype.name = className ServerError.prototype.status = code ServerError.prototype.statusCode = code ServerError.prototype.expose = false diff --git a/package.json b/package.json index 4cb6d7e..e4ba520 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,6 @@ "repository": "jshttp/http-errors", "dependencies": { "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" }, diff --git a/test/test.js b/test/test.js index 0059d01..55156ed 100644 --- a/test/test.js +++ b/test/test.js @@ -5,6 +5,7 @@ var assert = require('assert') var util = require('util') var createError = require('..') +const { HttpError } = createError describe('createError(status)', function () { it('should create error object', function () { @@ -407,3 +408,20 @@ describe('HTTP Errors', function () { /* eslint-enable node/no-deprecated-api */ }) }) + +describe('Inheritance', function () { + it('should support subclasses', function () { + class MyError extends HttpError { + } + const err = new MyError() + assert.ok(err instanceof HttpError, 'subclass instances are instances of HttpError') + }) + + it('should set status and message', function () { + class MyError extends HttpError { + } + const err = new MyError(202, 'My Error') + assert.strictEqual(err.status, 202) + assert.strictEqual(err.message, 'My Error') + }) +})