| /*! | 
 |  * http-errors | 
 |  * Copyright(c) 2014 Jonathan Ong | 
 |  * Copyright(c) 2016 Douglas Christopher Wilson | 
 |  * MIT Licensed | 
 |  */ | 
 |  | 
 | 'use strict' | 
 |  | 
 | /** | 
 |  * Module dependencies. | 
 |  * @private | 
 |  */ | 
 |  | 
 | var deprecate = require('depd')('http-errors') | 
 | var setPrototypeOf = require('setprototypeof') | 
 | var statuses = require('statuses') | 
 | var inherits = require('inherits') | 
 | var toIdentifier = require('toidentifier') | 
 |  | 
 | /** | 
 |  * Module exports. | 
 |  * @public | 
 |  */ | 
 |  | 
 | module.exports = createError | 
 | module.exports.HttpError = createHttpErrorConstructor() | 
 |  | 
 | // Populate exports for all constructors | 
 | populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError) | 
 |  | 
 | /** | 
 |  * Get the code class of a status code. | 
 |  * @private | 
 |  */ | 
 |  | 
 | function codeClass (status) { | 
 |   return Number(String(status).charAt(0) + '00') | 
 | } | 
 |  | 
 | /** | 
 |  * Create a new HTTP Error. | 
 |  * | 
 |  * @returns {Error} | 
 |  * @public | 
 |  */ | 
 |  | 
 | function createError () { | 
 |   // so much arity going on ~_~ | 
 |   var err | 
 |   var msg | 
 |   var status = 500 | 
 |   var props = {} | 
 |   for (var i = 0; i < arguments.length; i++) { | 
 |     var arg = arguments[i] | 
 |     if (arg instanceof Error) { | 
 |       err = arg | 
 |       status = err.status || err.statusCode || status | 
 |       continue | 
 |     } | 
 |     switch (typeof arg) { | 
 |       case 'string': | 
 |         msg = arg | 
 |         break | 
 |       case 'number': | 
 |         status = arg | 
 |         if (i !== 0) { | 
 |           deprecate('non-first-argument status code; replace with createError(' + arg + ', ...)') | 
 |         } | 
 |         break | 
 |       case 'object': | 
 |         props = arg | 
 |         break | 
 |     } | 
 |   } | 
 |  | 
 |   if (typeof status === 'number' && (status < 400 || status >= 600)) { | 
 |     deprecate('non-error status code; use only 4xx or 5xx status codes') | 
 |   } | 
 |  | 
 |   if (typeof status !== 'number' || | 
 |     (!statuses[status] && (status < 400 || status >= 600))) { | 
 |     status = 500 | 
 |   } | 
 |  | 
 |   // constructor | 
 |   var HttpError = createError[status] || createError[codeClass(status)] | 
 |  | 
 |   if (!err) { | 
 |     // create error | 
 |     err = HttpError | 
 |       ? new HttpError(msg) | 
 |       : new Error(msg || statuses[status]) | 
 |     Error.captureStackTrace(err, createError) | 
 |   } | 
 |  | 
 |   if (!HttpError || !(err instanceof HttpError) || err.status !== status) { | 
 |     // add properties to generic error | 
 |     err.expose = status < 500 | 
 |     err.status = err.statusCode = status | 
 |   } | 
 |  | 
 |   for (var key in props) { | 
 |     if (key !== 'status' && key !== 'statusCode') { | 
 |       err[key] = props[key] | 
 |     } | 
 |   } | 
 |  | 
 |   return err | 
 | } | 
 |  | 
 | /** | 
 |  * Create HTTP error abstract base class. | 
 |  * @private | 
 |  */ | 
 |  | 
 | function createHttpErrorConstructor () { | 
 |   function HttpError () { | 
 |     throw new TypeError('cannot construct abstract class') | 
 |   } | 
 |  | 
 |   inherits(HttpError, Error) | 
 |  | 
 |   return HttpError | 
 | } | 
 |  | 
 | /** | 
 |  * Create a constructor for a client error. | 
 |  * @private | 
 |  */ | 
 |  | 
 | function createClientErrorConstructor (HttpError, name, code) { | 
 |   var className = name.match(/Error$/) ? name : name + 'Error' | 
 |  | 
 |   function ClientError (message) { | 
 |     // create the error object | 
 |     var msg = message != null ? message : statuses[code] | 
 |     var err = new Error(msg) | 
 |  | 
 |     // capture a stack trace to the construction point | 
 |     Error.captureStackTrace(err, ClientError) | 
 |  | 
 |     // adjust the [[Prototype]] | 
 |     setPrototypeOf(err, ClientError.prototype) | 
 |  | 
 |     // redefine the error message | 
 |     Object.defineProperty(err, 'message', { | 
 |       enumerable: true, | 
 |       configurable: true, | 
 |       value: msg, | 
 |       writable: true | 
 |     }) | 
 |  | 
 |     // redefine the error name | 
 |     Object.defineProperty(err, 'name', { | 
 |       enumerable: false, | 
 |       configurable: true, | 
 |       value: className, | 
 |       writable: true | 
 |     }) | 
 |  | 
 |     return err | 
 |   } | 
 |  | 
 |   inherits(ClientError, HttpError) | 
 |   nameFunc(ClientError, className) | 
 |  | 
 |   ClientError.prototype.status = code | 
 |   ClientError.prototype.statusCode = code | 
 |   ClientError.prototype.expose = true | 
 |  | 
 |   return ClientError | 
 | } | 
 |  | 
 | /** | 
 |  * Create a constructor for a server error. | 
 |  * @private | 
 |  */ | 
 |  | 
 | function createServerErrorConstructor (HttpError, name, code) { | 
 |   var className = name.match(/Error$/) ? name : name + 'Error' | 
 |  | 
 |   function ServerError (message) { | 
 |     // create the error object | 
 |     var msg = message != null ? message : statuses[code] | 
 |     var err = new Error(msg) | 
 |  | 
 |     // capture a stack trace to the construction point | 
 |     Error.captureStackTrace(err, ServerError) | 
 |  | 
 |     // adjust the [[Prototype]] | 
 |     setPrototypeOf(err, ServerError.prototype) | 
 |  | 
 |     // redefine the error message | 
 |     Object.defineProperty(err, 'message', { | 
 |       enumerable: true, | 
 |       configurable: true, | 
 |       value: msg, | 
 |       writable: true | 
 |     }) | 
 |  | 
 |     // redefine the error name | 
 |     Object.defineProperty(err, 'name', { | 
 |       enumerable: false, | 
 |       configurable: true, | 
 |       value: className, | 
 |       writable: true | 
 |     }) | 
 |  | 
 |     return err | 
 |   } | 
 |  | 
 |   inherits(ServerError, HttpError) | 
 |   nameFunc(ServerError, className) | 
 |  | 
 |   ServerError.prototype.status = code | 
 |   ServerError.prototype.statusCode = code | 
 |   ServerError.prototype.expose = false | 
 |  | 
 |   return ServerError | 
 | } | 
 |  | 
 | /** | 
 |  * Set the name of a function, if possible. | 
 |  * @private | 
 |  */ | 
 |  | 
 | function nameFunc (func, name) { | 
 |   var desc = Object.getOwnPropertyDescriptor(func, 'name') | 
 |  | 
 |   if (desc && desc.configurable) { | 
 |     desc.value = name | 
 |     Object.defineProperty(func, 'name', desc) | 
 |   } | 
 | } | 
 |  | 
 | /** | 
 |  * Populate the exports object with constructors for every error class. | 
 |  * @private | 
 |  */ | 
 |  | 
 | function populateConstructorExports (exports, codes, HttpError) { | 
 |   codes.forEach(function forEachCode (code) { | 
 |     var CodeError | 
 |     var name = toIdentifier(statuses[code]) | 
 |  | 
 |     switch (codeClass(code)) { | 
 |       case 400: | 
 |         CodeError = createClientErrorConstructor(HttpError, name, code) | 
 |         break | 
 |       case 500: | 
 |         CodeError = createServerErrorConstructor(HttpError, name, code) | 
 |         break | 
 |     } | 
 |  | 
 |     if (CodeError) { | 
 |       // export the constructor | 
 |       exports[code] = CodeError | 
 |       exports[name] = CodeError | 
 |     } | 
 |   }) | 
 |  | 
 |   // backwards-compatibility | 
 |   exports["I'mateapot"] = deprecate.function(exports.ImATeapot, | 
 |     '"I\'mateapot"; use "ImATeapot" instead') | 
 | } |