The LM Control website. Simple yet efficient.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*!
  2. * http-errors
  3. * Copyright(c) 2014 Jonathan Ong
  4. * Copyright(c) 2016 Douglas Christopher Wilson
  5. * MIT Licensed
  6. */
  7. 'use strict'
  8. /**
  9. * Module dependencies.
  10. * @private
  11. */
  12. var deprecate = require('depd')('http-errors')
  13. var setPrototypeOf = require('setprototypeof')
  14. var statuses = require('statuses')
  15. var inherits = require('inherits')
  16. var toIdentifier = require('toidentifier')
  17. /**
  18. * Module exports.
  19. * @public
  20. */
  21. module.exports = createError
  22. module.exports.HttpError = createHttpErrorConstructor()
  23. module.exports.isHttpError = createIsHttpErrorFunction(module.exports.HttpError)
  24. // Populate exports for all constructors
  25. populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError)
  26. /**
  27. * Get the code class of a status code.
  28. * @private
  29. */
  30. function codeClass (status) {
  31. return Number(String(status).charAt(0) + '00')
  32. }
  33. /**
  34. * Create a new HTTP Error.
  35. *
  36. * @returns {Error}
  37. * @public
  38. */
  39. function createError () {
  40. // so much arity going on ~_~
  41. var err
  42. var msg
  43. var status = 500
  44. var props = {}
  45. for (var i = 0; i < arguments.length; i++) {
  46. var arg = arguments[i]
  47. if (arg instanceof Error) {
  48. err = arg
  49. status = err.status || err.statusCode || status
  50. continue
  51. }
  52. switch (typeof arg) {
  53. case 'string':
  54. msg = arg
  55. break
  56. case 'number':
  57. status = arg
  58. if (i !== 0) {
  59. deprecate('non-first-argument status code; replace with createError(' + arg + ', ...)')
  60. }
  61. break
  62. case 'object':
  63. props = arg
  64. break
  65. }
  66. }
  67. if (typeof status === 'number' && (status < 400 || status >= 600)) {
  68. deprecate('non-error status code; use only 4xx or 5xx status codes')
  69. }
  70. if (typeof status !== 'number' ||
  71. (!statuses[status] && (status < 400 || status >= 600))) {
  72. status = 500
  73. }
  74. // constructor
  75. var HttpError = createError[status] || createError[codeClass(status)]
  76. if (!err) {
  77. // create error
  78. err = HttpError
  79. ? new HttpError(msg)
  80. : new Error(msg || statuses[status])
  81. Error.captureStackTrace(err, createError)
  82. }
  83. if (!HttpError || !(err instanceof HttpError) || err.status !== status) {
  84. // add properties to generic error
  85. err.expose = status < 500
  86. err.status = err.statusCode = status
  87. }
  88. for (var key in props) {
  89. if (key !== 'status' && key !== 'statusCode') {
  90. err[key] = props[key]
  91. }
  92. }
  93. return err
  94. }
  95. /**
  96. * Create HTTP error abstract base class.
  97. * @private
  98. */
  99. function createHttpErrorConstructor () {
  100. function HttpError () {
  101. throw new TypeError('cannot construct abstract class')
  102. }
  103. inherits(HttpError, Error)
  104. return HttpError
  105. }
  106. /**
  107. * Create a constructor for a client error.
  108. * @private
  109. */
  110. function createClientErrorConstructor (HttpError, name, code) {
  111. var className = toClassName(name)
  112. function ClientError (message) {
  113. // create the error object
  114. var msg = message != null ? message : statuses[code]
  115. var err = new Error(msg)
  116. // capture a stack trace to the construction point
  117. Error.captureStackTrace(err, ClientError)
  118. // adjust the [[Prototype]]
  119. setPrototypeOf(err, ClientError.prototype)
  120. // redefine the error message
  121. Object.defineProperty(err, 'message', {
  122. enumerable: true,
  123. configurable: true,
  124. value: msg,
  125. writable: true
  126. })
  127. // redefine the error name
  128. Object.defineProperty(err, 'name', {
  129. enumerable: false,
  130. configurable: true,
  131. value: className,
  132. writable: true
  133. })
  134. return err
  135. }
  136. inherits(ClientError, HttpError)
  137. nameFunc(ClientError, className)
  138. ClientError.prototype.status = code
  139. ClientError.prototype.statusCode = code
  140. ClientError.prototype.expose = true
  141. return ClientError
  142. }
  143. /**
  144. * Create function to test is a value is a HttpError.
  145. * @private
  146. */
  147. function createIsHttpErrorFunction (HttpError) {
  148. return function isHttpError (val) {
  149. if (!val || typeof val !== 'object') {
  150. return false
  151. }
  152. if (val instanceof HttpError) {
  153. return true
  154. }
  155. return val instanceof Error &&
  156. typeof val.expose === 'boolean' &&
  157. typeof val.statusCode === 'number' && val.status === val.statusCode
  158. }
  159. }
  160. /**
  161. * Create a constructor for a server error.
  162. * @private
  163. */
  164. function createServerErrorConstructor (HttpError, name, code) {
  165. var className = toClassName(name)
  166. function ServerError (message) {
  167. // create the error object
  168. var msg = message != null ? message : statuses[code]
  169. var err = new Error(msg)
  170. // capture a stack trace to the construction point
  171. Error.captureStackTrace(err, ServerError)
  172. // adjust the [[Prototype]]
  173. setPrototypeOf(err, ServerError.prototype)
  174. // redefine the error message
  175. Object.defineProperty(err, 'message', {
  176. enumerable: true,
  177. configurable: true,
  178. value: msg,
  179. writable: true
  180. })
  181. // redefine the error name
  182. Object.defineProperty(err, 'name', {
  183. enumerable: false,
  184. configurable: true,
  185. value: className,
  186. writable: true
  187. })
  188. return err
  189. }
  190. inherits(ServerError, HttpError)
  191. nameFunc(ServerError, className)
  192. ServerError.prototype.status = code
  193. ServerError.prototype.statusCode = code
  194. ServerError.prototype.expose = false
  195. return ServerError
  196. }
  197. /**
  198. * Set the name of a function, if possible.
  199. * @private
  200. */
  201. function nameFunc (func, name) {
  202. var desc = Object.getOwnPropertyDescriptor(func, 'name')
  203. if (desc && desc.configurable) {
  204. desc.value = name
  205. Object.defineProperty(func, 'name', desc)
  206. }
  207. }
  208. /**
  209. * Populate the exports object with constructors for every error class.
  210. * @private
  211. */
  212. function populateConstructorExports (exports, codes, HttpError) {
  213. codes.forEach(function forEachCode (code) {
  214. var CodeError
  215. var name = toIdentifier(statuses[code])
  216. switch (codeClass(code)) {
  217. case 400:
  218. CodeError = createClientErrorConstructor(HttpError, name, code)
  219. break
  220. case 500:
  221. CodeError = createServerErrorConstructor(HttpError, name, code)
  222. break
  223. }
  224. if (CodeError) {
  225. // export the constructor
  226. exports[code] = CodeError
  227. exports[name] = CodeError
  228. }
  229. })
  230. // backwards-compatibility
  231. exports["I'mateapot"] = deprecate.function(exports.ImATeapot,
  232. '"I\'mateapot"; use "ImATeapot" instead')
  233. }
  234. /**
  235. * Get a class name from a name identifier.
  236. * @private
  237. */
  238. function toClassName (name) {
  239. return name.substr(-5) !== 'Error'
  240. ? name + 'Error'
  241. : name
  242. }