Search code examples
javascriptcustom-exceptions

Shorter way to define custom JavaScript exceptions?


I'm defining custom JavaScript exceptions like the code below. Is this proper? Isn't there a shorter way?

function InvalidModuleError(moduleName) {
    TypeError.apply(this);
    this.message = "module '" + moduleName + "' doesn't export any definitions";
    this.name = 'InvalidModuleError';
};

InvalidModuleError.prototype = Object.create(TypeError.prototype);


function DuplicateModuleError(moduleName) {
    TypeError.apply(this);
    this.message = "module '" + moduleName + "' is already defined";
    this.name = 'DuplicateModuleError';
};

DuplicateModuleError.prototype = Object.create(TypeError.prototype);

Edit: Eventually, after Oriol's suggestion, I've made a function that generates exceptions and looks like this:

function makeException(parentObject, parentClass, name, message) {
    var shortName = name.split('.');
    shortName = shortName[shortName.length - 1];
    parentObject[shortName] = function() {
        this.message = (typeof message === 'function') ? message.apply(null, arguments) : message;
    };
    parentObject[shortName].prototype = Object.create(parentClass.prototype, {'name': {'value': name}});
}

Solution

  • Your code can be simplified a bit:

    function InvalidModuleError(moduleName) {
        this.message = "module '" + moduleName + "' doesn't export any definitions";
    }
    InvalidModuleError.prototype = new Error();
    InvalidModuleError.prototype.name = 'InvalidModuleError';
    
    function DuplicateModuleError(moduleName) {
        this.message = "module '" + moduleName + "' is already defined";
    }
    DuplicateModuleError.prototype = new Error();
    DuplicateModuleError.prototype.name = 'DuplicateModuleError';
    

    But if you want to have lots of custom exceptions, better use

    function newModuleError(errorName, message) {
        var moduleError = function(moduleName) {
            this.message = message.replace('%s', moduleName);
        };
        moduleError.prototype = new Error();
        moduleError.prototype.name = errorName;
        return moduleError; 
    };
    
    var InvalidModuleError = newModuleError('InvalidModuleError', "module '%s' doesn't export any definitions"),
        DuplicateModuleError = newModuleError('DuplicateModuleError', "module '%s' is already defined");
    

    To throw them:

    throw new InvalidModuleError("moduleName1");
    throw new DuplicateModuleError("moduleName2");