From 341f92577cda7a2a71cdfa7893859d4b3dbe153e Mon Sep 17 00:00:00 2001 From: Justin Fagnani Date: Sat, 20 Jul 2024 16:18:26 -0700 Subject: [PATCH 1/2] Remove inherits and setprototypeof deps, use real classes --- index.js | 103 +++++++++++++-------------------------------------- package.json | 2 - test/test.js | 18 +++++++++ 3 files changed, 43 insertions(+), 80 deletions(-) diff --git a/index.js b/index.js index c425f1e..6a950e0 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. @@ -104,21 +112,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 +120,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 +166,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') + }) +}) From 58fa0028df1312cf178f52dc38fdc0680fee9c36 Mon Sep 17 00:00:00 2001 From: Justin Fagnani Date: Sun, 21 Jul 2024 10:16:57 -0700 Subject: [PATCH 2/2] Remove Error.captureStackTrace --- index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/index.js b/index.js index 6a950e0..d66f2e4 100644 --- a/index.js +++ b/index.js @@ -94,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) {