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:
