m3-cqw
1.701K
· January 2014 ·
Dsc 9420

Subclassing Error in JavaScript is harder than it seems

Unfortunately Error() function in JS is not a typical constructor and standard methods with Error.call(this) or Error.apply(this) will not work correctly. From the spec:

15.11.1 The Error Constructor Called as a Function

When Error is called as a function rather than as a constructor, it creates and initialises a new Error object. Thus the function call Error(…) is equivalent to the object creation expression new Error(…) with the same arguments.

The next best thing you can do is to pretend to subclass it and then copy properties you want:

function HttpError(code, msg) {
    this.message = msg;
    this.statusCode = code;
    this.name = 'HttpError';
    const err = Error(msg); // http://es5.github.io/#x15.11.1
    this.stack = err.stack;
}

HttpError.prototype = Object.create(Error.prototype);
HttpError.prototype.constructor = HttpError;

The code above passes these tests:

const err = new HttpError(404, "Test");

assert(err instanceof Error);
assert(err instanceof HttpError);
assert.equal(err.name, 'HttpError');
assert.equal(err.statusCode, 404);
assert(util.isError(err));
// These would fail if you relied on Error.call(this, msg)
assert.include(err.stack, __filename);
assert.equal(err.message, 'Test'); 
Sign in or sign up to add your response.