| |
| var statuses = require('statuses'); |
| var inherits = require('inherits'); |
| |
| function toIdentifier(str) { |
| return str.split(' ').map(function (token) { |
| return token.slice(0, 1).toUpperCase() + token.slice(1) |
| }).join('').replace(/[^ _0-9a-z]/gi, '') |
| } |
| |
| exports = module.exports = function httpError() { |
| // 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; |
| break; |
| case 'object': |
| props = arg; |
| break; |
| } |
| } |
| |
| if (typeof status !== 'number' || !statuses[status]) { |
| status = 500 |
| } |
| |
| // constructor |
| var HttpError = exports[status] |
| |
| if (!err) { |
| // create error |
| err = HttpError |
| ? new HttpError(msg) |
| : new Error(msg || statuses[status]) |
| Error.captureStackTrace(err, httpError) |
| } |
| |
| if (!HttpError || !(err instanceof HttpError)) { |
| // 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 generic error objects |
| var codes = statuses.codes.filter(function (num) { |
| return num >= 400; |
| }); |
| |
| codes.forEach(function (code) { |
| var name = toIdentifier(statuses[code]) |
| var className = name.match(/Error$/) ? name : name + 'Error' |
| |
| if (code >= 500) { |
| var ServerError = function ServerError(msg) { |
| var self = new Error(msg != null ? msg : statuses[code]) |
| Error.captureStackTrace(self, ServerError) |
| self.__proto__ = ServerError.prototype |
| Object.defineProperty(self, 'name', { |
| enumerable: false, |
| configurable: true, |
| value: className, |
| writable: true |
| }) |
| return self |
| } |
| inherits(ServerError, Error); |
| ServerError.prototype.status = |
| ServerError.prototype.statusCode = code; |
| ServerError.prototype.expose = false; |
| exports[code] = |
| exports[name] = ServerError |
| return; |
| } |
| |
| var ClientError = function ClientError(msg) { |
| var self = new Error(msg != null ? msg : statuses[code]) |
| Error.captureStackTrace(self, ClientError) |
| self.__proto__ = ClientError.prototype |
| Object.defineProperty(self, 'name', { |
| enumerable: false, |
| configurable: true, |
| value: className, |
| writable: true |
| }) |
| return self |
| } |
| inherits(ClientError, Error); |
| ClientError.prototype.status = |
| ClientError.prototype.statusCode = code; |
| ClientError.prototype.expose = true; |
| exports[code] = |
| exports[name] = ClientError |
| return; |
| }); |
| |
| // backwards-compatibility |
| exports["I'mateapot"] = exports.ImATeapot |