Documentation

property

JS_ERRORS

exports.JS_ERRORS

JavaScript Error constructors indexed by name
for convenience.

Examples

new errors.JS_ERRORS.URIError('Malformed URI');

    exports.JS_ERRORS = {
        Error: Error
        , EvalError: EvalError
        , RangeError: RangeError
        , ReferenceError: ReferenceError
        , SyntaxError: SyntaxError
        , TypeError: TypeError
        , URIError: URIError
    };
    method

    find

    exports.find()

    Returns the error constructor by the given code or
    name.

    Examples

    errors.find(404);
    // => Http404Error

    errors.find(500);
    // => Http500Error

    errors.find('Http401Error');
    // => http401Error

    • @param: {String,Number} err
    • @returns:
    exports.find = function(err) {
        return (typeof err == 'number') ? codes[err] : names[err];
    };
    declaration

    create

    create

    Create a new constructor instance based
    on the given options.

    This factory method allows consumers to build
    parameterized error constructor function instances
    which can then be used to instantiate new concrete
    instances of the given error.

    This method accepts jQuery style options argument
    with the following properties (note that name is
    the only required property, all others are optional).

    The scope option can be used to change the default
    namespace to create the constructor in. If unspecified
    it defaults to the exports object of this module
    (i.e. errors.exports).

    The parent option specifies the parent to inherit
    from. If unspecified it defaults to Error.

    The defaultMessage, defaultExplanation and
    defaultResponse define the default text to use
    for the new errors message, explanation and
    response respectively. These values can be
    overridden at construction time.

    The code specifies the error code for the new
    error. If unspecified it defaults to a generated
    error number which is greater than or equal to
    600.

    Examples

    // use all defaults
    errors.create({name: 'FileNotFoundError'});
    throw new errors.FileNotFoundError("Could not find file x");

    // inheritance
    errors.create({
    name: 'FatalError',
    code: 900
    });
    errors.create({
    name: 'DatabaseError',
    parent: errors.FatalError
    code: 901
    });
    var dbe = new errors.DatabaseError("Internal database error");
    dbe instanceof errors.FatalError;
    // => true

    // scoping to current module exports
    var MalformedEncodingError = errors.create({
    name: 'MalformedEncodingError',
    scope: exports
    });
    throw new MalformedEncodingError("Encoding not supported");

    // default message
    errors.create({
    name: 'SocketReadError',
    code: 4000,
    defaultMessage: 'Could not read from socket'
    });
    var sre = new errors.SocketReadError();
    sre.message;
    // => 'Could not read from socket'
    sre.code;
    // => 4000
    sre instanceof Error;
    // => true

    // explanation and response
    errors.create({
    name: 'SocketReadError',
    code: 4000,
    defaultMessage: 'Could not read from socket',
    defaultExplanation: 'Unable to obtain a reference to the socket',
    defaultResponse: 'Specify a different port or socket and retry the operation'
    });
    var sre = new errors.SocketReadError();
    sre.explanation;
    // => 'Unable to obtain a reference to the socket'
    sre.response;
    // => 'Specify a different port or socket and retry the operation'

    • @param: {String} name The constructor name.
    • @param: {Object} scope The scope (i.e. namespace).
    • @param: {Function} parent The parent to inherit from.
    • @param: {String} defaultMessage The default message.
    • @param: {Number} code The error code.
    • @param: {String} defaultExplanation The default explanation.
    • @param: {String} defaultResponse The default operator response.
    • @return: {Function} the newly created constructor
    var create = exports.create = function(options) {
        var options = options || {}
            , scope = options.scope || exports
            , parent = options.parent || Error
            , defaultMessage = options.defaultMessage
                || 'An unexpected ' + options.name + ' occurred.'
            , className = options.name
            , errorCode = options.code || nextCode()
            , defaultExplanation = options.defaultExplanation
            , defaultResponse= options.defaultResponse
            , formattedStack
            , stack = {};

    Create a new instance of the exception optionally
    specifying a message, explanation and response
    for the new instance. If any of the arguments are
    null, their value will default to their respective
    default value use on the create call, or will
    be null if no default was specified.

    • @param: {String} msg The message to use for the error.
    • @param: {String} expl The explanation to use for the error.
    • @param: {String} fix The response to use for the error.
    • @return: {Object} The newly created error.
    scope[className] = function(msg, expl, fix) {
            msg = msg || defaultMessage;
            expl = expl || defaultExplanation;
            fix = fix || defaultResponse;
    
            parent.call(this, msg);
    
            // hack around the defineProperty for stack so
            // we can delay stack formatting until access
            // for performance reasons
            Error.captureStackTrace(stack, scope[className]);

    Return the stack tracks for the error.

    • @return: {String}
    Object.defineProperty(this, 'stack', {
                configurable: true,
                enumerable: false,
                get: function() {
                    if (!formattedStack) {
                        formattedStack = stack.stack.replace('[object Object]', 'Error: ' + msg);
                    }
                    return formattedStack;
                }
            });

    Return the explanation for this error.

    • @return: {String}
    Object.defineProperty(this, 'explanation', {
                value: expl,
                configurable: true,
                enumerable: true
            });

    Return the operator response for this error.

    • @return: {String}
    Object.defineProperty(this, 'response', {
                value: fix,
                configurable: true,
                enumerable: true
            });

    Return the error code.

    • @return: {Number}
    Object.defineProperty(this, 'code', {
                value: errorCode,
                configurable: true,
                enumerable: true
            });

    HTTP status code of this error.

    If the instance's code is not a valid
    HTTP status code it's normalized to 500.s

    • @return: {Number}
    Object.defineProperty(this, 'status', {
                value: http.STATUS_CODES[errorCode] ? errorCode : 500,
                configurable: true,
                // normalize for http status code and connect compat
                enumerable: true
            });

    Name of this error.

    • @return: {String}
    Object.defineProperty(this, 'name', {
                value: className,
                configurable: true,
                enumerable: true
            });

    Message for this error.

    • @return: {String}
    Object.defineProperty(this, 'message', {
                value: msg,
                configurable: true,
                enumerable: true
            });
        };
    
        util.inherits(scope[className], parent);

    Return the name of the prototype.

    • @return: {String}
    Object.defineProperty(scope[className].prototype, 'name', {
            value: className,
            enumerable: true
        });

    Return a formatted string for this error which
    includes the error's name, message and code.
    The string will also include the explanation and
    response if they are set for this instance.

    Can be redefined by consumers to change formatting.

    • @return: {String}
    scope[className].prototype.toString = function() {

    Return the JSON representation of this error
    which includes it's name, code, message
    and status. The JSON object returned will
    also include the explanation and response
    if defined for this instance.

    This method can be redefined for customized
    behavior of JSON.stringify().

    • @return: {Object}
    scope[className].prototype.toJSON = function() {
            // TODO externalization
            return useStack
                    ? mixin(this, {stack: this.stack}, true)
                    : mixin(this, {}, true);
        };
    
        cache(className, errorCode, scope[className]);
    
        return scope[className];
    };
    method

    stacks

    exports.stacks()

    Get/set the module default behavior in terms of if
    stack traces should be included in toString(),
    send()ing errors, etc.

    When called with no parameters this method will return
    if the errors module is set to use stacks or not.

    When called with a single boolean parameter this
    method will interally set if stack traces should be used.

    • @param: {Boolean} useStacks
    exports.stacks = function(useStacks) {
        if (useStacks == null || useStacks == undefined) {
            return useStack;
        }
        useStack = useStacks;
    };
    method

    title

    exports.title()

    Gets/sets the module's default page title to use for
    html based responses.

    If called with no arguments, returns the current title
    set. Otherwise when called with a single String argument
    sets the title to use for html based responses.

    The default title is 'Error'.

    • @param: {String} title The title to use.
    exports.title = function(title) {
        if (title == null || title == undefined) {
            return pageTitle;
        }
        pageTitle = title;
    };

    Base Error for web app HTTP based
    exceptions -- all 4xx and 5xx wrappered
    errors are instances of HttpError.

      create({name: 'HttpError'});

      HttpErrors for all 4xx-5xx HTTP based status codes
      defined as Http[code]Error for convenience.

      Examples

      // Accept: text/html
      res.send(new errors.Http404Error('Resource not found'));
      // => text/html
      // => "Resource not found"

      // Accept: application/json
      res.send(new errors.Http423Error('Resource is currently locked'));
      // => application/json
      // {
      // "name": "Http423Error",
      // "code": 423,
      // "status": 423,
      // "message": "Resource is currently locked"
      // }

      // Accept: text/plain
      // res.send(new errors.Http401Error('You do not have access'));
      // => text/plain
      // "You do not have access"

        for (code in http.STATUS_CODES) {
            // TODO: provide default explanation & response
            if (http.STATUS_CODES.hasOwnProperty(code) && code >= 400) {
                create({
                    name: 'Http' + code + 'Error',
                    code: code,
                    parent: exports.HttpError,
                    defaultMessage: http.STATUS_CODES[code]
                });
            }
        }
        method

        errorHandler

        exports.errorHandler()

        Custom error handler middleware based on connect's
        errorHandler() middleware. Althought out of the box
        connect or express errorHandler() works just fine,
        its not as pretty as you might like due to the additional
        details in custom error's toString().

        Therefore errors exports its own errorHandler()
        middleware which supports an options object to configure
        it.

        The options JSON object accepts the following properties:

        • @param: {String} title The title to use for html based responses which overrides module `title()`.
        • @param: {Boolean} connectCompat True to create connect compat html responses.
        • @param: {Boolean} includeStack True if the custom error handler should include the stack.
        exports.errorHandler = function(options) {
                var opts = mixin({connectCompat: false, title: pageTitle, includeStack: useStack}
                        , options, true);
                if (opts.connectCompat) {
                    return function(err, req, res, next) {
                        if (isError(err)) {
                            // connect errorHandler() compat
                            err.toString = function() {
                                return err.message;
                            };
                        }
                        errHandler.title = opts.title;
                        // connect middleware error handler
                        return errHandler()(err, req, res, next);
                    };
                } else {
                    return defaultFormatter(opts.title, opts.includeStack);
                }
            };
        }

        If Express is installed, patch response to
        permit sending Error based objects. If
        vanilla Error objects are used with send,
        they are mapped by default to the Http500Error.

        Prior to sending an error based response, any
        mapper setup for the Error is invoked allowing
        customization or transformation of the error.

        The current implementation provides direct support
        for text/html, text/plain and application/json
        based accept types, otherwise it defaults to plain/text.

        Examples

        // Accept: text/html
        res.send(new errors.Http404Error('Resource not found'));
        // => html
        // => html structured response

        // Accept: application/json
        res.send(new errors.Http423Error('Resource is currently locked'));
        // => application/json
        // => {
        // => 'name': 'Http423Error',
        // => 'code': 423,
        // => 'status': 423,
        // => 'message': 'Resource is currently locked'
        // => }

        // Accept: text/plain
        // res.send(new errors.Http401Error('You do not have access'));
        // => text/plain
        // => "You do not have access"

        // Accept: text/xml
        // res.send(new errors.Http500Error('Something bad happened'));
        // => 500
        // => text/plain

          if (response) {
              var _send = response.send;
              response.send = function(err) {
                  if (arguments.length == 1 && err instanceof Error) {
                      err = mapError(err);
                      if (!isError(err)) {
                          // map vanilla errors into 500s
                          err = new exports.Http500Error(err.message ||
                                  http.STATUS_CODES[500] + ' - ' + err.name);
                      }
                      defaultFormatter(pageTitle, useStack)(err, this.req, this.req.res, null);
                      return this;
                  }
                  return _send.apply(this, arguments);
              };
          }
          declaration

          mapper

          mapper

          Adds or retrieves an error mappers.

          When called with 2 arguments, this method is used to
          add error mappers for the given error names.

          When called with a single argument it's used to
          retrieve the registered mapper for the given
          error name.

          Any bound mappers will be invoked
          for express.send() integration and hence you
          can define mappers used when sending error responses
          with Express.

          Examples

          // adding mappers
          errors.mapper('RangeError', function(rangeError) {
          return new errors.Http412Error('Invalid range requested');
          })
          .addmapper('ReferenceError', function(refError) {
          return new errors.Http424Error('Bad reference given');
          });

          errors.mapper(['RangeError', 'ReferenceError'], function(err) {
          return new errors.Http500Error(err.message);
          });

          // retrieve error mapper
          var rangeError = errors.mapper('RangeError');

          • @param: {String,Array} errName The error name(s) to attach the mapper to.
          • @param: {Function} fn The function to call for the mapping.
          • @returns:
          • @retrieved:
          var mapper = exports.mapper = function(errName, fn) {
              if (arguments.length == 2) {
                  asArray(errName).forEach(function(name) {
                      mappers[name] = fn;
                  });
                  return exports;
              }
              return mappers[errName];
          };
          declaration

          mapError

          mapError

          Maps the given error using the bound error mapper
          and returns the mapped error as per the mappers
          return value. If no mapper is bound to the given
          errors name, the argument error is returned unchanged.

          Examples

          errors.mapError(new RangeError());

          • @param: {Object} err The error instance to map.
          • @returns:
          var mapError = exports.mapError = function(err) {
              return mapper(err.name) ? mapper(err.name)(err) : err;
          };