var statusCodes = require('http').STATUS_CODES;

/**
 * Expose middleware.
 */

module.exports = errorHandlerFactory;

/**
 * Error middleware.
 */

function errorHandlerFactory(options) {

  options = options || {};

  // Default view to `"error"`.
  options.view = options.view || 'error';

  // Default exitOnUncaughtException to `true`.
  options.exitOnUncaughtException = options.exitOnUncaughtException !== undefined ?
    options.exitOnUncaughtException :
    true;

  // Default exitCode to `1`.
  options.exitCode = options.exitCode !== undefined ?
    options.exitCode :
    1;

  return function errorHandler(err, req, res, next) {
    // Default statusCode to 500.
    var status = err.status || 500;

    if (options.exitOnUncaughtException && ! isClientError(status)) {
      res.once('finish', process.exit.bind(process, options.exitCode));
    }

    // Send status code.
    res.status(status);

    // Format error according to accepted format.
    res.format({
      'json': function () {
        res.send(status, errorToJson(err));
      },
      'html': function () {
        res.render(options.view, {
          error: err,
          status: status,
          statusMessage: statusCodes[status]
        });
      },
      'text': function () {
        res.send(status, err.message || statusCodes[status]);
      }
    });
  };
}

/**
 * Format an error in JSON plain object.
 *
 * @param {Error|mixed} error
 * @returns {Object}
 */

function errorToJson(error) {
  return { error : { message: error.message || error, code: error.code || null } };
}

/**
 * Test if it's a client error.
 *
 * @param {String} status
 * @returns {Boolean}
 */

function isClientError(status) {
  return (status >= 400 && status <= 499);
}
@@ -286,16 +286,271 @@
 rror';%0A%0A
+  // Default status to 500%0A  options.status = options.status %7C%7C 500;%0A%0A  // Default formatters%0A  options.formatters = options.formatters %7C%7C %5B'json', 'text', 'html'%5D;%0A%0A  // Default formatter%0A  options.defaultFormatter = options.defaultFormatter %7C%7C 'html';%0A%0A
   // Def
@@ -837,16 +837,17 @@
     1;%0A%0A
+%0A
   return
@@ -953,27 +953,38 @@
 r.status %7C%7C 
-500
+options.status
 ;%0A%0A    if (o
@@ -1184,66 +1184,63 @@
  // 
-Format error according to accepted
+Set Available
  format
-.
+ters
 %0A    
-res.format(
+var availableFormatters = 
 %7B%0A  
@@ -1594,24 +1594,396 @@
      %7D%0A    %7D
+;%0A%0A    var formatters = %7B%7D%0A    options.formatters.forEach(function(f) %7B%0A      if (f in availableFormatters) %7B%0A        formatters%5Bf%5D = availableFormatters%5Bf%5D;%0A      %7D%0A    %7D);%0A%0A    if (options.defaultFormatter in formatters) %7B%0A      formatters.default = formatters%5Boptions.defaultFormatter%5D;%0A    %7D%0A%0A    // Format error according to accepted format.%0A    res.format(formatters
 );%0A  %7D;%0A%7D%0A%0A/
@@ -2181,20 +2181,22 @@
 : error.
-code
+status
  %7C%7C null
@@ -2373,8 +2373,10 @@
  499);%0A%7D
+%0A%0A

Add a optional list of available formatters and a default formatter option