--- /dev/null
+
+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