Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// TypeScript definitions for http-errors

export interface HttpError extends Error {
status: number;
statusCode: number;
expose: boolean;
}

interface CreateHttpError {
(status: number, message?: string): HttpError;
(status: number, err: Error, props?: object): HttpError;
(status: number, props: object): HttpError;
(message: string, status?: number): HttpError;
(err: Error, props?: object): HttpError;
HttpError: {
new(status: number, message?: string): HttpError;
};
isHttpError(val: any): boolean;
}

declare const createError: CreateHttpError;
export = createError;
14 changes: 9 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,16 @@ function createError () {
*/

function createHttpErrorConstructor () {
function HttpError () {
throw new TypeError('cannot construct abstract class')
class HttpError extends Error {
constructor (status, message) {
super(message != null ? message : statuses.message[status] || 'Error')
this.status = status != null ? status : 500
this.statusCode = this.status
this.expose = this.status < 500
// Set the name for consistency
this.name = 'HttpError'
}
}

inherits(HttpError, Error)

return HttpError
}

Expand Down
27 changes: 24 additions & 3 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ describe('createError(status)', function () {
assert.ok(isError(createError(500)))
})

describe('ES6 class extension (issue #98)', function () {
it('should allow extending HttpError with ES6 class', function () {
class MyHttpError extends createError.HttpError {
constructor (message) {
super(418, message)
this.custom = true
}
}
const err = new MyHttpError('I am a teapot')
assert.strictEqual(err.status, 418)
assert.strictEqual(err.message, 'I am a teapot')
assert.strictEqual(err.custom, true)
assert.ok(err instanceof createError.HttpError)
assert.ok(err instanceof Error)
})
})

describe('Extending Existing Errors with HTTP Properties', function () {
it('should extend existing error without altering its prototype or replacing the object', function () {
var nativeError = new Error('This is a test error')
Expand Down Expand Up @@ -377,9 +394,13 @@ describe('HTTP Errors', function () {
})

it('new createError.HttpError()', function () {
assert.throws(function () {
new createError.HttpError() // eslint-disable-line no-new
}, /cannot construct abstract class/)
var err = new createError.HttpError(404, 'Not Found')
assert.strictEqual(err.name, 'HttpError')
assert.strictEqual(err.message, 'Not Found')
assert.strictEqual(err.status, 404)
assert.strictEqual(err.statusCode, 404)
assert.strictEqual(err.expose, true)
assert(err.stack)
})

it('new createError.NotFound()', function () {
Expand Down
20 changes: 20 additions & 0 deletions test/typings.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// TypeScript compilation test for http-errors
import { HttpError } from '../index';
import * as createError from '../index';

// Test that HttpError can be used as a type
let err: HttpError = createError(404, 'not found');
err.status;
err.expose;

// Test that HttpError can be extended (workaround for abstract class)
class MyHttpError extends (createError.HttpError as { new(status: number, message: string): HttpError }) {
custom: boolean;
constructor(message: string) {
super(418, message);
this.custom = true;
}
}
const myErr = new MyHttpError('I am a teapot');
myErr.status;
myErr.custom;