| |
| |
| |
| |
| |
|
|
|
|
| 'use strict'
|
|
|
| |
| |
| |
|
|
|
|
| var deprecate = require('depd')('http-errors')
|
| var setPrototypeOf = require('setprototypeof')
|
| var statuses = require('statuses')
|
| var inherits = require('inherits')
|
| var toIdentifier = require('toidentifier')
|
|
|
| |
| |
| |
|
|
|
|
| module.exports = createError
|
| module.exports.HttpError = createHttpErrorConstructor()
|
| module.exports.isHttpError = createIsHttpErrorFunction(module.exports.HttpError)
|
|
|
|
|
| populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError)
|
|
|
| |
| |
| |
|
|
|
|
| function codeClass (status) {
|
| return Number(String(status).charAt(0) + '00')
|
| }
|
|
|
| |
| |
| |
| |
| |
|
|
|
|
| function createError () {
|
|
|
| var err
|
| var msg
|
| var status = 500
|
| var props = {}
|
| for (var i = 0; i < arguments.length; i++) {
|
| var arg = arguments[i]
|
| var type = typeof arg
|
| if (type === 'object' && arg instanceof Error) {
|
| err = arg
|
| status = err.status || err.statusCode || status
|
| } else if (type === 'number' && i === 0) {
|
| status = arg
|
| } else if (type === 'string') {
|
| msg = arg
|
| } else if (type === 'object') {
|
| props = arg
|
| } else {
|
| throw new TypeError('argument #' + (i + 1) + ' unsupported type ' + type)
|
| }
|
| }
|
|
|
| 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.message[status] && (status < 400 || status >= 600))) {
|
| status = 500
|
| }
|
|
|
|
|
| var HttpError = createError[status] || createError[codeClass(status)]
|
|
|
| if (!err) {
|
|
|
| err = HttpError
|
| ? new HttpError(msg)
|
| : new Error(msg || statuses.message[status])
|
| Error.captureStackTrace(err, createError)
|
| }
|
|
|
| if (!HttpError || !(err instanceof HttpError) || err.status !== status) {
|
|
|
| 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
|
| }
|
|
|
| |
| |
| |
|
|
|
|
| function createHttpErrorConstructor () {
|
| function HttpError () {
|
| throw new TypeError('cannot construct abstract class')
|
| }
|
|
|
| inherits(HttpError, Error)
|
|
|
| return HttpError
|
| }
|
|
|
| |
| |
| |
|
|
|
|
| function createClientErrorConstructor (HttpError, name, code) {
|
| var className = toClassName(name)
|
|
|
| function ClientError (message) {
|
|
|
| var msg = message != null ? message : statuses.message[code]
|
| var err = new Error(msg)
|
|
|
|
|
| Error.captureStackTrace(err, ClientError)
|
|
|
|
|
| setPrototypeOf(err, ClientError.prototype)
|
|
|
|
|
| Object.defineProperty(err, 'message', {
|
| enumerable: true,
|
| configurable: true,
|
| value: msg,
|
| writable: true
|
| })
|
|
|
|
|
| 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
|
| }
|
|
|
| |
| |
| |
|
|
|
|
| function createIsHttpErrorFunction (HttpError) {
|
| return function isHttpError (val) {
|
| if (!val || typeof val !== 'object') {
|
| return false
|
| }
|
|
|
| if (val instanceof HttpError) {
|
| return true
|
| }
|
|
|
| return val instanceof Error &&
|
| typeof val.expose === 'boolean' &&
|
| typeof val.statusCode === 'number' && val.status === val.statusCode
|
| }
|
| }
|
|
|
| |
| |
| |
|
|
|
|
| function createServerErrorConstructor (HttpError, name, code) {
|
| var className = toClassName(name)
|
|
|
| function ServerError (message) {
|
|
|
| var msg = message != null ? message : statuses.message[code]
|
| var err = new Error(msg)
|
|
|
|
|
| Error.captureStackTrace(err, ServerError)
|
|
|
|
|
| setPrototypeOf(err, ServerError.prototype)
|
|
|
|
|
| Object.defineProperty(err, 'message', {
|
| enumerable: true,
|
| configurable: true,
|
| value: msg,
|
| writable: true
|
| })
|
|
|
|
|
| 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
|
| }
|
|
|
| |
| |
| |
|
|
|
|
| function nameFunc (func, name) {
|
| var desc = Object.getOwnPropertyDescriptor(func, 'name')
|
|
|
| if (desc && desc.configurable) {
|
| desc.value = name
|
| Object.defineProperty(func, 'name', desc)
|
| }
|
| }
|
|
|
| |
| |
| |
|
|
|
|
| function populateConstructorExports (exports, codes, HttpError) {
|
| codes.forEach(function forEachCode (code) {
|
| var CodeError
|
| var name = toIdentifier(statuses.message[code])
|
|
|
| switch (codeClass(code)) {
|
| case 400:
|
| CodeError = createClientErrorConstructor(HttpError, name, code)
|
| break
|
| case 500:
|
| CodeError = createServerErrorConstructor(HttpError, name, code)
|
| break
|
| }
|
|
|
| if (CodeError) {
|
|
|
| exports[code] = CodeError
|
| exports[name] = CodeError
|
| }
|
| })
|
| }
|
|
|
| |
| |
| |
| |
| |
| |
|
|
|
|
| function toClassName (name) {
|
| return name.slice(-5) === 'Error' ? name : name + 'Error'
|
| }
|
|
|