How do I create a custom Error in JavaScript?
JavascriptExceptionJavascript Problem Overview
For some reason it looks like constructor delegation doesn't work in the following snippet:
function NotImplementedError() {
Error.apply(this, arguments);
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")
Running this gives The message is: ''
. Any ideas as to why, or if there is a better way to create a new Error
subclass? Is there a problem with apply
ing to the native Error
constructor that I don't know about?
Javascript Solutions
Solution 1 - Javascript
Update your code to assign your prototype to the Error.prototype and the instanceof and your asserts work.
function NotImplementedError(message = "") {
this.name = "NotImplementedError";
this.message = message;
}
NotImplementedError.prototype = Error.prototype;
However, I would just throw your own object and just check the name property.
throw {name : "NotImplementedError", message : "too lazy to implement"};
Edit based on comments
After looking at the comments and trying to remember why I would assign prototype to Error.prototype
instead of new Error()
like Nicholas Zakas did in his article, I created a jsFiddle with the code below:
function NotImplementedError(message = "") {
this.name = "NotImplementedError";
this.message = message;
}
NotImplementedError.prototype = Error.prototype;
function NotImplementedError2(message = "") {
this.message = message;
}
NotImplementedError2.prototype = new Error();
try {
var e = new NotImplementedError("NotImplementedError message");
throw e;
} catch (ex1) {
console.log(ex1.stack);
console.log("ex1 instanceof NotImplementedError = " + (ex1 instanceof NotImplementedError));
console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
console.log("ex1.name = " + ex1.name);
console.log("ex1.message = " + ex1.message);
}
try {
var e = new NotImplementedError2("NotImplementedError2 message");
throw e;
} catch (ex1) {
console.log(ex1.stack);
console.log("ex1 instanceof NotImplementedError2 = " + (ex1 instanceof NotImplementedError2));
console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
console.log("ex1.name = " + ex1.name);
console.log("ex1.message = " + ex1.message);
}
The console output was this.
undefined
ex1 instanceof NotImplementedError = true
ex1 instanceof Error = true
ex1.name = NotImplementedError
ex1.message = NotImplementedError message
Error
at window.onload (http://fiddle.jshell.net/MwMEJ/show/:29:34)
ex1 instanceof NotImplementedError2 = true
ex1 instanceof Error = true
ex1.name = Error
ex1.message = NotImplementedError2 message
This confirmes the "problem" I ran into was the stack property of the error was the line number where new Error()
was created, and not where the throw e
occurred. However, that may be better that having the side effect of a NotImplementedError.prototype.name = "NotImplementedError"
line affecting the Error object.
Also, notice with NotImplementedError2
, when I don't set the .name
explicitly, it is equal to "Error". However, as mentioned in the comments, because that version sets prototype to new Error()
, I could set NotImplementedError2.prototype.name = "NotImplementedError2"
and be OK.
Solution 2 - Javascript
In ES2015, you can use class
to do this cleanly:
class NotImplemented extends Error {
constructor(message = "", ...args) {
super(message, ...args);
this.message = message + " has not yet been implemented.";
}
}
This does not modify the global Error
prototype, allows you to customize message
, name
, and other attributes, and properly captures the stack. It's also pretty readable.
Of course, you may need to use a tool like babel
if your code will be running on older browsers.
Solution 3 - Javascript
All of the above answers are terrible awful - really. Even the one with 107 ups! The real answer is here guys:
TL;DR:
A. The reason message
isn't being set is that Error
is a function that returns a new Error object and does not manipulate this
in any way.
B. The way to do this right is to return the result of the apply from the constructor, as well as setting the prototype in the usual complicated javascripty way:
function MyError() {
var temp = Error.apply(this, arguments);
temp.name = this.name = 'MyError';
this.message = temp.message;
if(Object.defineProperty) {
// getter for more optimizy goodness
/*this.stack = */Object.defineProperty(this, 'stack', {
get: function() {
return temp.stack
},
configurable: true // so you can change it if you want
})
} else {
this.stack = temp.stack
}
}
//inherit prototype using ECMAScript 5 (IE 9+)
MyError.prototype = Object.create(Error.prototype, {
constructor: {
value: MyError,
writable: true,
configurable: true
}
});
var myError = new MyError("message");
console.log("The message is: '" + myError.message + "'"); // The message is: 'message'
console.log(myError instanceof Error); // true
console.log(myError instanceof MyError); // true
console.log(myError.toString()); // MyError: message
console.log(myError.stack); // MyError: message \n
// <stack trace ...>
//for EMCAScript 4 or ealier (IE 8 or ealier), inherit prototype this way instead of above code:
/*
var IntermediateInheritor = function() {};
IntermediateInheritor.prototype = Error.prototype;
MyError.prototype = new IntermediateInheritor();
*/
You could probably do some trickery to enumerate through all the non-enumerable properties of the tmp
Error to set them rather than explicitly setting only stack
and message
, but the trickery isn't supported in ie<9
Solution 4 - Javascript
If anyone is curious on how to create a custom error and get the stack trace:
function CustomError(message) {
this.name = 'CustomError';
this.message = message || '';
var error = new Error(this.message);
error.name = this.name;
this.stack = error.stack;
}
CustomError.prototype = Object.create(Error.prototype);
try {
throw new CustomError('foobar');
}
catch (e) {
console.log('name:', e.name);
console.log('message:', e.message);
console.log('stack:', e.stack);
}
Solution 5 - Javascript
This section of the standard may explain why the Error.apply
call doesn't initialize the object:
> 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.
In this case the Error
function probably determines that it's not being called as a constructor, so it returns a new Error instance rather than initializing the this
object.
Testing with the following code seems to demonstrate that this is in fact what's happening:
function NotImplementedError() {
var returned = Error.apply(this, arguments);
console.log("returned.message = '" + returned.message + "'");
console.log("this.message = '" + this.message + "'");
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
The following output is generated when this is run:
returned.message = 'some message'
this.message = ''
Solution 6 - Javascript
function InvalidValueError(value, type) {
this.message = "Expected `" + type.name + "`: " + value;
var error = new Error(this.message);
this.stack = error.stack;
}
InvalidValueError.prototype = new Error();
InvalidValueError.prototype.name = InvalidValueError.name;
InvalidValueError.prototype.constructor = InvalidValueError;
Solution 7 - Javascript
Accoring to Joyent you shouldn’t mess with the stack property (which I see in lots of answers given here), because it will have a negative impact on performance. Here is what they say:
> stack: generally, don't mess with this. Don't even augment it. V8 only computes it if someone actually reads the property, which improves performance dramatically for handlable errors. If you read the property just to augment it, you'll end up paying the cost even if your caller doesn't need the stack.
I like and would like to mention their idea of wrapping the original error which is a nice replacement for passing on the stack.
So here is how I create a custom error, considering the above mentioned:
es5 version:
function RError(options) {
options = options || {}; // eslint-disable-line no-param-reassign
this.name = options.name;
this.message = options.message;
this.cause = options.cause;
// capture stack (this property is supposed to be treated as private)
this._err = new Error();
// create an iterable chain
this.chain = this.cause ? [this].concat(this.cause.chain) : [this];
}
RError.prototype = Object.create(Error.prototype, {
constructor: {
value: RError,
writable: true,
configurable: true
}
});
Object.defineProperty(RError.prototype, 'stack', {
get: function stack() {
return this.name + ': ' + this.message + '\n' + this._err.stack.split('\n').slice(2).join('\n');
}
});
Object.defineProperty(RError.prototype, 'why', {
get: function why() {
var _why = this.name + ': ' + this.message;
for (var i = 1; i < this.chain.length; i++) {
var e = this.chain[i];
_why += ' <- ' + e.name + ': ' + e.message;
}
return _why;
}
});
// usage
function fail() {
throw new RError({
name: 'BAR',
message: 'I messed up.'
});
}
function failFurther() {
try {
fail();
} catch (err) {
throw new RError({
name: 'FOO',
message: 'Something went wrong.',
cause: err
});
}
}
try {
failFurther();
} catch (err) {
console.error(err.why);
console.error(err.stack);
console.error(err.cause.stack);
}
es6 version:
class RError extends Error {
constructor({name, message, cause}) {
super();
this.name = name;
this.message = message;
this.cause = cause;
}
[Symbol.iterator]() {
let current = this;
let done = false;
const iterator = {
next() {
const val = current;
if (done) {
return { value: val, done: true };
}
current = current.cause;
if (!val.cause) {
done = true;
}
return { value: val, done: false };
}
};
return iterator;
}
get why() {
let _why = '';
for (const e of this) {
_why += `${_why.length ? ' <- ' : ''}${e.name}: ${e.message}`;
}
return _why;
}
}
// usage
function fail() {
throw new RError({
name: 'BAR',
message: 'I messed up.'
});
}
function failFurther() {
try {
fail();
} catch (err) {
throw new RError({
name: 'FOO',
message: 'Something went wrong.',
cause: err
});
}
}
try {
failFurther();
} catch (err) {
console.error(err.why);
console.error(err.stack);
console.error(err.cause.stack);
}
I’ve put my solution into a module, here it is: https://www.npmjs.com/package/rerror
Solution 8 - Javascript
I like to do it like this:
- Make use of name so toString() throws
"{code}: {message}"
- Return same thing to super so it appears the same in the stacktrace
- Attach code to
error.code
as checking/parsing a code is better in code than checking a message, which you might want to localize for example - Attach message to
error.message
as an alternative toerror.toString()
class AppException extends Error {
constructor(code, message) {
const fullMsg = message ? `${code}: ${message}` : code;
super(fullMsg);
this.name = code;
this.code = code;
this.message = fullMsg;
}
toString() {
return this.message;
}
}
// Just a code
try {
throw new AppException('FORBIDDEN');
} catch(e) {
console.error(e);
console.error(e.toString());
console.log(e.code === 'FORBIDDEN');
}
// A code and a message
try {
throw new AppException('FORBIDDEN', 'You don\'t have access to this page');
} catch(e) {
console.error(e);
console.error(e.toString());
console.log(e.code === 'FORBIDDEN');
}
Solution 9 - Javascript
I had a similar issue to this. My error needs to be an instanceof
both Error
and NotImplemented
, and it also needs to produce a coherent backtrace in the console.
My solution:
var NotImplemented = (function() {
var NotImplemented, err;
NotImplemented = (function() {
function NotImplemented(message) {
var err;
err = new Error(message);
err.name = "NotImplemented";
this.message = err.message;
if (err.stack) this.stack = err.stack;
}
return NotImplemented;
})();
err = new Error();
err.name = "NotImplemented";
NotImplemented.prototype = err;
return NotImplemented;
}).call(this);
// TEST:
console.log("instanceof Error: " + (new NotImplemented() instanceof Error));
console.log("instanceof NotImplemented: " + (new NotImplemented() instanceofNotImplemented));
console.log("message: "+(new NotImplemented('I was too busy').message));
throw new NotImplemented("just didn't feel like it");
Result of running with node.js:
instanceof Error: true
instanceof NotImplemented: true
message: I was too busy
/private/tmp/t.js:24
throw new NotImplemented("just didn't feel like it");
^
NotImplemented: just didn't feel like it
at Error.NotImplemented (/Users/colin/projects/gems/jax/t.js:6:13)
at Object.<anonymous> (/Users/colin/projects/gems/jax/t.js:24:7)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.runMain (module.js:487:10)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
The error passes all 3 of my criteria, and although the stack
property is nonstandard, it is supported in most newer browsers which is acceptable in my case.
Solution 10 - Javascript
class NotImplementedError extends Error {
constructor(message) {
super(message);
this.message = message;
}
}
NotImplementedError.prototype.name = 'NotImplementedError';
module.exports = NotImplementedError;
and
try {
var e = new NotImplementedError("NotImplementedError message");
throw e;
} catch (ex1) {
console.log(ex1.stack);
console.log("ex1 instanceof NotImplementedError = " + (ex1 instanceof NotImplementedError));
console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
console.log("ex1.name = " + ex1.name);
console.log("ex1.message = " + ex1.message);
}
It is just a class representation of this answer.
output
NotImplementedError: NotImplementedError message
...stacktrace
ex1 instanceof NotImplementedError = true
ex1 instanceof Error = true
ex1.name = NotImplementedError
ex1.message = NotImplementedError message
Solution 11 - Javascript
I used the Constructor Pattern to create the new error object. I defined the prototype chain such as an Error
instance. See the MDN Error constructor reference.
You can check this snippet on this gist.
IMPLEMENTATION
// Creates user-defined exceptions
var CustomError = (function() {
'use strict';
//constructor
function CustomError() {
//enforces 'new' instance
if (!(this instanceof CustomError)) {
return new CustomError(arguments);
}
var error,
//handles the arguments object when is passed by enforcing a 'new' instance
args = Array.apply(null, typeof arguments[0] === 'object' ? arguments[0] : arguments),
message = args.shift() || 'An exception has occurred';
//builds the message with multiple arguments
if (~message.indexOf('}')) {
args.forEach(function(arg, i) {
message = message.replace(RegExp('\\{' + i + '}', 'g'), arg);
});
}
//gets the exception stack
error = new Error(message);
//access to CustomError.prototype.name
error.name = this.name;
//set the properties of the instance
//in order to resemble an Error instance
Object.defineProperties(this, {
stack: {
enumerable: false,
get: function() { return error.stack; }
},
message: {
enumerable: false,
value: message
}
});
}
// Creates the prototype and prevents the direct reference to Error.prototype;
// Not used new Error() here because an exception would be raised here,
// but we need to raise the exception when CustomError instance is created.
CustomError.prototype = Object.create(Error.prototype, {
//fixes the link to the constructor (ES5)
constructor: setDescriptor(CustomError),
name: setDescriptor('JSU Error')
});
function setDescriptor(value) {
return {
configurable: false,
enumerable: false,
writable: false,
value: value
};
}
//returns the constructor
return CustomError;
}());
USAGE
The CustomError constructor can receive many arguments to build the message, e.g.
var err1 = new CustomError("The url of file is required"),
err2 = new CustomError("Invalid Date: {0}", +"date"),
err3 = new CustomError("The length must be greater than {0}", 4),
err4 = new CustomError("Properties .{0} and .{1} don't exist", "p1", "p2");
throw err4;
And this is how the custom error looks:
Solution 12 - Javascript
I just had to implement something like this and found that the stack was lost in my own error implementation. What I had to do was create a dummy error and retrieve the stack from that:
My.Error = function (message, innerException) {
var err = new Error();
this.stack = err.stack; // IMPORTANT!
this.name = "Error";
this.message = message;
this.innerException = innerException;
}
My.Error.prototype = new Error();
My.Error.prototype.constructor = My.Error;
My.Error.prototype.toString = function (includeStackTrace) {
var msg = this.message;
var e = this.innerException;
while (e) {
msg += " The details are:\n" + e.message;
e = e.innerException;
}
if (includeStackTrace) {
msg += "\n\nStack Trace:\n\n" + this.stack;
}
return msg;
}
Solution 13 - Javascript
This is my implementation:
class HttpError extends Error {
constructor(message, code = null, status = null, stack = null, name = null) {
super();
this.message = message;
this.status = 500;
this.name = name || this.constructor.name;
this.code = code || `E_${this.name.toUpperCase()}`;
this.stack = stack || null;
}
static fromObject(error) {
if (error instanceof HttpError) {
return error;
}
else {
const { message, code, status, stack } = error;
return new ServerError(message, code, status, stack, error.constructor.name);
}
}
expose() {
if (this instanceof ClientError) {
return { ...this };
}
else {
return {
name: this.name,
code: this.code,
status: this.status,
}
}
}
}
class ServerError extends HttpError {}
class ClientError extends HttpError { }
class IncorrectCredentials extends ClientError {
constructor(...args) {
super(...args);
this.status = 400;
}
}
class ResourceNotFound extends ClientError {
constructor(...args) {
super(...args);
this.status = 404;
}
}
Example usage #1:
app.use((req, res, next) => {
try {
invalidFunction();
}
catch (err) {
const error = HttpError.fromObject(err);
return res.status(error.status).send(error.expose());
}
});
Example usage #2:
router.post('/api/auth', async (req, res) => {
try {
const isLogged = await User.logIn(req.body.username, req.body.password);
if (!isLogged) {
throw new IncorrectCredentials('Incorrect username or password');
}
else {
return res.status(200).send({
token,
});
}
}
catch (err) {
const error = HttpError.fromObject(err);
return res.status(error.status).send(error.expose());
}
});
Solution 14 - Javascript
The constructor needs to be like a factory method and return what you want. If you need additional methods/properties, you can add them to the object before returning it.
function NotImplementedError(message) { return new Error("Not implemented", message); }
x = new NotImplementedError();
Though I'm not sure why you'd need to do this. Why not just use new Error...
? Custom exceptions don't really add much in JavaScript (or probably any untyped language).
Solution 15 - Javascript
This is implemented nicely in the Cesium DeveloperError:
In it's simplified form:
var NotImplementedError = function(message) {
this.name = 'NotImplementedError';
this.message = message;
this.stack = (new Error()).stack;
}
// Later on...
throw new NotImplementedError();
Solution 16 - Javascript
At the expense of not being able to use instanceof
, the following preserves the original stack trace and doesn't use any non-standard tricks.
// the function itself
var fixError = function(err, name) {
err.name = name;
return err;
}
// using the function
try {
throw fixError(new Error('custom error message'), 'CustomError');
} catch (e) {
if (e.name == 'CustomError')
console.log('Wee! Custom Error! Msg:', e.message);
else
throw e; // unhandled. let it propagate upwards the call stack
}
Solution 17 - Javascript
Another alternative , might not work in all enviroments.Atleast assured it works in nodejs 0.8 This approach uses a non standard way of modifying the internal proto prop
function myError(msg){
var e = new Error(msg);
_this = this;
_this.__proto__.__proto__ = e;
}
Solution 18 - Javascript
If you are using Node/Chrome. The following snippet will get you extension which meets the following requirements.
err instanceof Error
err instanceof CustomErrorType
- console.log() returns
[CustomErrorType]
when created with a message - console.log() returns
[CustomErrorType: message]
when created without a message - throw/stack provides the information at the point the error was created.
- Works optimally in Node.JS, and Chrome.
- Will pass instanceof checks in Chrome, Safari, Firefox and IE 8+, but will not have a valid stack outside of Chrome/Safari. I'm OK with that because I can debug in chrome, but code which requires specific error types will still function cross browser. If you need Node only you can easily remove the
if
statements and you're good to go.
Snippet
var CustomErrorType = function(message) {
if (Object.defineProperty) {
Object.defineProperty(this, "message", {
value : message || "",
enumerable : false
});
} else {
this.message = message;
}
if (Error.captureStackTrace) {
Error.captureStackTrace(this, CustomErrorType);
}
}
CustomErrorType.prototype = new Error();
CustomErrorType.prototype.name = "CustomErrorType";
Usage
var err = new CustomErrorType("foo");
Output
var err = new CustomErrorType("foo");
console.log(err);
console.log(err.stack);
[CustomErrorType: foo]
CustomErrorType: foo
at Object.<anonymous> (/errorTest.js:27:12)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:906:3
/errorTest.js:30
throw err;
^
CustomErrorType: foo
at Object.<anonymous> (/errorTest.js:27:12)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:906:3
Solution 19 - Javascript
The following worked for me taken from the official Mozilla documentation Error.
function NotImplementedError(message) {
var instance = new Error(message);
instance.name = 'NotImplementedError';
Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
if (Error.captureStackTrace) {
Error.captureStackTrace(instance, NotImplementedError);
}
return instance;
}
NotImplementedError.prototype = Object.create(Error.prototype, {
constructor: {
value: Error,
enumerable: false,
writable: true,
configurable: true
}
});
Solution 20 - Javascript
Try a new prototype object for each instance of the user defined error type. It allows instanceof
checks to behave as usual plus type and message are correctly reported in Firefox and V8 (Chome, nodejs).
function NotImplementedError(message){
if(NotImplementedError.innercall===undefined){
NotImplementedError.innercall = true;
NotImplementedError.prototype = new Error(message);
NotImplementedError.prototype.name = "NotImplementedError";
NotImplementedError.prototype.constructor = NotImplementedError;
return new NotImplementedError(message);
}
delete NotImplementedError.innercall;
}
Note that an additional entry will preceed the otherwise correct stack.
Solution 21 - Javascript
This is fastest way to do it:
let thisVar = false
if (thisVar === false) {
throw new Error("thisVar is false. It should be true.")
}
Solution 22 - Javascript
easier way. You could make your object inherit from the Error object. Example:
function NotImplementError(message)
{
this.message = message;
Error.call();
Error.call(message);
}
what we are doing is using the function call() which call the constructor of the Error class so is basicly the same thing as implementing a class inheritance in other object oriented languages.
Solution 23 - Javascript
MDN has an excellent example:
try {
throw new Error('Whoops!');
} catch (e) {
console.log(e.name + ': ' + e.message);
}