node-fastify 5.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/.borp.yaml +3 -0
  2. package/.markdownlint-cli2.yaml +22 -0
  3. package/.prettierignore +1 -0
  4. package/GOVERNANCE.md +4 -0
  5. package/LICENSE +21 -0
  6. package/PROJECT_CHARTER.md +126 -0
  7. package/README.md +423 -0
  8. package/SECURITY.md +220 -0
  9. package/SPONSORS.md +24 -0
  10. package/build/build-error-serializer.js +35 -0
  11. package/build/build-validation.js +169 -0
  12. package/build/sync-version.js +11 -0
  13. package/docs/Guides/Benchmarking.md +60 -0
  14. package/docs/Guides/Database.md +321 -0
  15. package/docs/Guides/Delay-Accepting-Requests.md +608 -0
  16. package/docs/Guides/Detecting-When-Clients-Abort.md +172 -0
  17. package/docs/Guides/Ecosystem.md +726 -0
  18. package/docs/Guides/Fluent-Schema.md +127 -0
  19. package/docs/Guides/Getting-Started.md +620 -0
  20. package/docs/Guides/Index.md +43 -0
  21. package/docs/Guides/Migration-Guide-V3.md +287 -0
  22. package/docs/Guides/Migration-Guide-V4.md +267 -0
  23. package/docs/Guides/Migration-Guide-V5.md +727 -0
  24. package/docs/Guides/Plugins-Guide.md +520 -0
  25. package/docs/Guides/Prototype-Poisoning.md +383 -0
  26. package/docs/Guides/Recommendations.md +378 -0
  27. package/docs/Guides/Serverless.md +604 -0
  28. package/docs/Guides/Style-Guide.md +246 -0
  29. package/docs/Guides/Testing.md +481 -0
  30. package/docs/Guides/Write-Plugin.md +103 -0
  31. package/docs/Guides/Write-Type-Provider.md +34 -0
  32. package/docs/Reference/ContentTypeParser.md +271 -0
  33. package/docs/Reference/Decorators.md +436 -0
  34. package/docs/Reference/Encapsulation.md +194 -0
  35. package/docs/Reference/Errors.md +377 -0
  36. package/docs/Reference/HTTP2.md +94 -0
  37. package/docs/Reference/Hooks.md +958 -0
  38. package/docs/Reference/Index.md +73 -0
  39. package/docs/Reference/LTS.md +86 -0
  40. package/docs/Reference/Lifecycle.md +99 -0
  41. package/docs/Reference/Logging.md +268 -0
  42. package/docs/Reference/Middleware.md +79 -0
  43. package/docs/Reference/Plugins.md +245 -0
  44. package/docs/Reference/Principles.md +73 -0
  45. package/docs/Reference/Reply.md +1001 -0
  46. package/docs/Reference/Request.md +295 -0
  47. package/docs/Reference/Routes.md +802 -0
  48. package/docs/Reference/Server.md +2389 -0
  49. package/docs/Reference/Type-Providers.md +256 -0
  50. package/docs/Reference/TypeScript.md +1729 -0
  51. package/docs/Reference/Validation-and-Serialization.md +1130 -0
  52. package/docs/Reference/Warnings.md +58 -0
  53. package/docs/index.md +24 -0
  54. package/docs/resources/encapsulation_context.drawio +1 -0
  55. package/docs/resources/encapsulation_context.svg +3 -0
  56. package/eslint.config.js +35 -0
  57. package/examples/asyncawait.js +38 -0
  58. package/examples/benchmark/body.json +3 -0
  59. package/examples/benchmark/hooks-benchmark-async-await.js +44 -0
  60. package/examples/benchmark/hooks-benchmark.js +52 -0
  61. package/examples/benchmark/parser.js +47 -0
  62. package/examples/benchmark/simple.js +30 -0
  63. package/examples/benchmark/webstream.js +27 -0
  64. package/examples/hooks.js +91 -0
  65. package/examples/http2.js +39 -0
  66. package/examples/https.js +38 -0
  67. package/examples/parser.js +53 -0
  68. package/examples/plugin.js +12 -0
  69. package/examples/route-prefix.js +38 -0
  70. package/examples/shared-schema.js +38 -0
  71. package/examples/simple-stream.js +20 -0
  72. package/examples/simple.js +32 -0
  73. package/examples/simple.mjs +27 -0
  74. package/examples/typescript-server.ts +79 -0
  75. package/examples/use-plugin.js +29 -0
  76. package/fastify.d.ts +253 -0
  77. package/fastify.js +985 -0
  78. package/integration/server.js +29 -0
  79. package/integration/test.sh +23 -0
  80. package/lib/config-validator.js +1266 -0
  81. package/lib/content-type-parser.js +413 -0
  82. package/lib/content-type.js +160 -0
  83. package/lib/context.js +98 -0
  84. package/lib/decorate.js +152 -0
  85. package/lib/error-handler.js +173 -0
  86. package/lib/error-serializer.js +134 -0
  87. package/lib/error-status.js +14 -0
  88. package/lib/errors.js +516 -0
  89. package/lib/four-oh-four.js +190 -0
  90. package/lib/handle-request.js +195 -0
  91. package/lib/head-route.js +45 -0
  92. package/lib/hooks.js +429 -0
  93. package/lib/initial-config-validation.js +37 -0
  94. package/lib/logger-factory.js +136 -0
  95. package/lib/logger-pino.js +68 -0
  96. package/lib/noop-set.js +10 -0
  97. package/lib/plugin-override.js +90 -0
  98. package/lib/plugin-utils.js +169 -0
  99. package/lib/promise.js +23 -0
  100. package/lib/reply.js +1030 -0
  101. package/lib/req-id-gen-factory.js +52 -0
  102. package/lib/request.js +391 -0
  103. package/lib/route.js +686 -0
  104. package/lib/schema-controller.js +164 -0
  105. package/lib/schemas.js +207 -0
  106. package/lib/server.js +441 -0
  107. package/lib/symbols.js +71 -0
  108. package/lib/validation.js +280 -0
  109. package/lib/warnings.js +57 -0
  110. package/lib/wrap-thenable.js +84 -0
  111. package/package.json +225 -0
  112. package/scripts/validate-ecosystem-links.js +179 -0
  113. package/test/404s.test.js +2035 -0
  114. package/test/500s.test.js +422 -0
  115. package/test/allow-unsafe-regex.test.js +92 -0
  116. package/test/als.test.js +65 -0
  117. package/test/async-await.test.js +705 -0
  118. package/test/async-dispose.test.js +20 -0
  119. package/test/async_hooks.test.js +52 -0
  120. package/test/body-limit.test.js +224 -0
  121. package/test/buffer.test.js +74 -0
  122. package/test/build/error-serializer.test.js +36 -0
  123. package/test/build/version.test.js +14 -0
  124. package/test/build-certificate.js +109 -0
  125. package/test/bundler/README.md +29 -0
  126. package/test/bundler/esbuild/bundler-test.js +32 -0
  127. package/test/bundler/esbuild/package.json +10 -0
  128. package/test/bundler/esbuild/src/fail-plugin-version.js +14 -0
  129. package/test/bundler/esbuild/src/index.js +9 -0
  130. package/test/bundler/webpack/bundler-test.js +32 -0
  131. package/test/bundler/webpack/package.json +11 -0
  132. package/test/bundler/webpack/src/fail-plugin-version.js +14 -0
  133. package/test/bundler/webpack/src/index.js +9 -0
  134. package/test/bundler/webpack/webpack.config.js +15 -0
  135. package/test/case-insensitive.test.js +102 -0
  136. package/test/chainable.test.js +40 -0
  137. package/test/child-logger-factory.test.js +128 -0
  138. package/test/client-timeout.test.js +38 -0
  139. package/test/close-pipelining.test.js +78 -0
  140. package/test/close.test.js +706 -0
  141. package/test/conditional-pino.test.js +47 -0
  142. package/test/connection-timeout.test.js +42 -0
  143. package/test/constrained-routes.test.js +1138 -0
  144. package/test/content-length.test.js +174 -0
  145. package/test/content-parser.test.js +739 -0
  146. package/test/content-type.test.js +181 -0
  147. package/test/context-config.test.js +164 -0
  148. package/test/custom-http-server.test.js +118 -0
  149. package/test/custom-parser-async.test.js +59 -0
  150. package/test/custom-parser.0.test.js +701 -0
  151. package/test/custom-parser.1.test.js +266 -0
  152. package/test/custom-parser.2.test.js +91 -0
  153. package/test/custom-parser.3.test.js +208 -0
  154. package/test/custom-parser.4.test.js +218 -0
  155. package/test/custom-parser.5.test.js +130 -0
  156. package/test/custom-querystring-parser.test.js +129 -0
  157. package/test/decorator.test.js +1330 -0
  158. package/test/delete.test.js +344 -0
  159. package/test/diagnostics-channel/404.test.js +49 -0
  160. package/test/diagnostics-channel/async-delay-request.test.js +65 -0
  161. package/test/diagnostics-channel/async-request.test.js +64 -0
  162. package/test/diagnostics-channel/error-before-handler.test.js +35 -0
  163. package/test/diagnostics-channel/error-request.test.js +53 -0
  164. package/test/diagnostics-channel/error-status.test.js +123 -0
  165. package/test/diagnostics-channel/init.test.js +50 -0
  166. package/test/diagnostics-channel/sync-delay-request.test.js +49 -0
  167. package/test/diagnostics-channel/sync-request-reply.test.js +51 -0
  168. package/test/diagnostics-channel/sync-request.test.js +54 -0
  169. package/test/encapsulated-child-logger-factory.test.js +69 -0
  170. package/test/encapsulated-error-handler.test.js +237 -0
  171. package/test/esm/errorCodes.test.mjs +10 -0
  172. package/test/esm/esm.test.mjs +13 -0
  173. package/test/esm/index.test.js +8 -0
  174. package/test/esm/named-exports.mjs +14 -0
  175. package/test/esm/other.mjs +8 -0
  176. package/test/esm/plugin.mjs +8 -0
  177. package/test/fastify-instance.test.js +300 -0
  178. package/test/find-route.test.js +152 -0
  179. package/test/fluent-schema.test.js +209 -0
  180. package/test/genReqId.test.js +426 -0
  181. package/test/handler-context.test.js +45 -0
  182. package/test/handler-timeout.test.js +367 -0
  183. package/test/has-route.test.js +88 -0
  184. package/test/header-overflow.test.js +55 -0
  185. package/test/helper.js +496 -0
  186. package/test/hooks-async.test.js +1099 -0
  187. package/test/hooks.on-listen.test.js +1162 -0
  188. package/test/hooks.on-ready.test.js +421 -0
  189. package/test/hooks.test.js +3578 -0
  190. package/test/http-methods/copy.test.js +35 -0
  191. package/test/http-methods/custom-http-methods.test.js +114 -0
  192. package/test/http-methods/get.test.js +412 -0
  193. package/test/http-methods/head.test.js +263 -0
  194. package/test/http-methods/lock.test.js +108 -0
  195. package/test/http-methods/mkcalendar.test.js +143 -0
  196. package/test/http-methods/mkcol.test.js +35 -0
  197. package/test/http-methods/move.test.js +42 -0
  198. package/test/http-methods/propfind.test.js +136 -0
  199. package/test/http-methods/proppatch.test.js +105 -0
  200. package/test/http-methods/report.test.js +142 -0
  201. package/test/http-methods/search.test.js +233 -0
  202. package/test/http-methods/trace.test.js +21 -0
  203. package/test/http-methods/unlock.test.js +38 -0
  204. package/test/http2/closing.test.js +270 -0
  205. package/test/http2/constraint.test.js +109 -0
  206. package/test/http2/head.test.js +34 -0
  207. package/test/http2/plain.test.js +68 -0
  208. package/test/http2/secure-with-fallback.test.js +113 -0
  209. package/test/http2/secure.test.js +67 -0
  210. package/test/http2/unknown-http-method.test.js +34 -0
  211. package/test/https/custom-https-server.test.js +58 -0
  212. package/test/https/https.test.js +136 -0
  213. package/test/imports.test.js +17 -0
  214. package/test/inject.test.js +502 -0
  215. package/test/input-validation.js +335 -0
  216. package/test/internals/all.test.js +38 -0
  217. package/test/internals/content-type-parser.test.js +111 -0
  218. package/test/internals/context.test.js +31 -0
  219. package/test/internals/decorator.test.js +156 -0
  220. package/test/internals/errors.test.js +982 -0
  221. package/test/internals/handle-request.test.js +270 -0
  222. package/test/internals/hook-runner.test.js +449 -0
  223. package/test/internals/hooks.test.js +96 -0
  224. package/test/internals/initial-config.test.js +383 -0
  225. package/test/internals/logger.test.js +163 -0
  226. package/test/internals/plugin.test.js +170 -0
  227. package/test/internals/promise.test.js +63 -0
  228. package/test/internals/reply-serialize.test.js +714 -0
  229. package/test/internals/reply.test.js +1920 -0
  230. package/test/internals/req-id-gen-factory.test.js +133 -0
  231. package/test/internals/request-validate.test.js +1402 -0
  232. package/test/internals/request.test.js +506 -0
  233. package/test/internals/schema-controller-perf.test.js +40 -0
  234. package/test/internals/server.test.js +91 -0
  235. package/test/internals/validation.test.js +352 -0
  236. package/test/issue-4959.test.js +118 -0
  237. package/test/keep-alive-timeout.test.js +42 -0
  238. package/test/listen.1.test.js +154 -0
  239. package/test/listen.2.test.js +113 -0
  240. package/test/listen.3.test.js +83 -0
  241. package/test/listen.4.test.js +168 -0
  242. package/test/listen.5.test.js +122 -0
  243. package/test/logger/instantiation.test.js +341 -0
  244. package/test/logger/logger-test-utils.js +47 -0
  245. package/test/logger/logging.test.js +460 -0
  246. package/test/logger/options.test.js +579 -0
  247. package/test/logger/request.test.js +292 -0
  248. package/test/logger/response.test.js +183 -0
  249. package/test/logger/tap-parallel-not-ok +0 -0
  250. package/test/max-requests-per-socket.test.js +113 -0
  251. package/test/middleware.test.js +37 -0
  252. package/test/noop-set.test.js +19 -0
  253. package/test/nullable-validation.test.js +187 -0
  254. package/test/options.error-handler.test.js +5 -0
  255. package/test/options.test.js +5 -0
  256. package/test/output-validation.test.js +140 -0
  257. package/test/patch.error-handler.test.js +5 -0
  258. package/test/patch.test.js +5 -0
  259. package/test/plugin.1.test.js +230 -0
  260. package/test/plugin.2.test.js +314 -0
  261. package/test/plugin.3.test.js +287 -0
  262. package/test/plugin.4.test.js +504 -0
  263. package/test/plugin.helper.js +8 -0
  264. package/test/plugin.name.display.js +10 -0
  265. package/test/post-empty-body.test.js +38 -0
  266. package/test/pretty-print.test.js +366 -0
  267. package/test/promises.test.js +125 -0
  268. package/test/proto-poisoning.test.js +145 -0
  269. package/test/put.error-handler.test.js +5 -0
  270. package/test/put.test.js +5 -0
  271. package/test/register.test.js +184 -0
  272. package/test/reply-code.test.js +148 -0
  273. package/test/reply-early-hints.test.js +100 -0
  274. package/test/reply-error.test.js +815 -0
  275. package/test/reply-trailers.test.js +445 -0
  276. package/test/reply-web-stream-locked.test.js +37 -0
  277. package/test/request-error.test.js +624 -0
  278. package/test/request-header-host.test.js +339 -0
  279. package/test/request-id.test.js +118 -0
  280. package/test/request-timeout.test.js +53 -0
  281. package/test/route-hooks.test.js +635 -0
  282. package/test/route-prefix.test.js +904 -0
  283. package/test/route-shorthand.test.js +48 -0
  284. package/test/route.1.test.js +259 -0
  285. package/test/route.2.test.js +100 -0
  286. package/test/route.3.test.js +213 -0
  287. package/test/route.4.test.js +127 -0
  288. package/test/route.5.test.js +211 -0
  289. package/test/route.6.test.js +306 -0
  290. package/test/route.7.test.js +406 -0
  291. package/test/route.8.test.js +225 -0
  292. package/test/router-options.test.js +1108 -0
  293. package/test/same-shape.test.js +124 -0
  294. package/test/schema-examples.test.js +661 -0
  295. package/test/schema-feature.test.js +2198 -0
  296. package/test/schema-serialization.test.js +1171 -0
  297. package/test/schema-special-usage.test.js +1348 -0
  298. package/test/schema-validation.test.js +1572 -0
  299. package/test/scripts/validate-ecosystem-links.test.js +339 -0
  300. package/test/serialize-response.test.js +186 -0
  301. package/test/server.test.js +347 -0
  302. package/test/set-error-handler.test.js +69 -0
  303. package/test/skip-reply-send.test.js +317 -0
  304. package/test/stream-serializers.test.js +40 -0
  305. package/test/stream.1.test.js +94 -0
  306. package/test/stream.2.test.js +129 -0
  307. package/test/stream.3.test.js +198 -0
  308. package/test/stream.4.test.js +176 -0
  309. package/test/stream.5.test.js +188 -0
  310. package/test/sync-routes.test.js +32 -0
  311. package/test/throw.test.js +359 -0
  312. package/test/toolkit.js +63 -0
  313. package/test/trust-proxy.test.js +162 -0
  314. package/test/type-provider.test.js +22 -0
  315. package/test/types/content-type-parser.test-d.ts +72 -0
  316. package/test/types/decorate-request-reply.test-d.ts +18 -0
  317. package/test/types/dummy-plugin.ts +9 -0
  318. package/test/types/errors.test-d.ts +90 -0
  319. package/test/types/fastify.test-d.ts +352 -0
  320. package/test/types/hooks.test-d.ts +550 -0
  321. package/test/types/import.ts +2 -0
  322. package/test/types/instance.test-d.ts +588 -0
  323. package/test/types/logger.test-d.ts +277 -0
  324. package/test/types/plugin.test-d.ts +97 -0
  325. package/test/types/register.test-d.ts +237 -0
  326. package/test/types/reply.test-d.ts +254 -0
  327. package/test/types/request.test-d.ts +188 -0
  328. package/test/types/route.test-d.ts +553 -0
  329. package/test/types/schema.test-d.ts +135 -0
  330. package/test/types/serverFactory.test-d.ts +37 -0
  331. package/test/types/type-provider.test-d.ts +1213 -0
  332. package/test/types/using.test-d.ts +17 -0
  333. package/test/upgrade.test.js +52 -0
  334. package/test/url-rewriting.test.js +122 -0
  335. package/test/use-semicolon-delimiter.test.js +168 -0
  336. package/test/validation-error-handling.test.js +900 -0
  337. package/test/versioned-routes.test.js +603 -0
  338. package/test/web-api.test.js +616 -0
  339. package/test/wrap-thenable.test.js +30 -0
  340. package/types/content-type-parser.d.ts +75 -0
  341. package/types/context.d.ts +22 -0
  342. package/types/errors.d.ts +92 -0
  343. package/types/hooks.d.ts +875 -0
  344. package/types/instance.d.ts +609 -0
  345. package/types/logger.d.ts +107 -0
  346. package/types/plugin.d.ts +44 -0
  347. package/types/register.d.ts +42 -0
  348. package/types/reply.d.ts +81 -0
  349. package/types/request.d.ts +95 -0
  350. package/types/route.d.ts +199 -0
  351. package/types/schema.d.ts +61 -0
  352. package/types/server-factory.d.ts +19 -0
  353. package/types/type-provider.d.ts +130 -0
  354. package/types/utils.d.ts +98 -0
package/lib/errors.js ADDED
@@ -0,0 +1,516 @@
1
+ 'use strict'
2
+
3
+ const createError = require('@fastify/error')
4
+
5
+ const codes = {
6
+ /**
7
+ * Basic
8
+ */
9
+ FST_ERR_NOT_FOUND: createError(
10
+ 'FST_ERR_NOT_FOUND',
11
+ 'Not Found',
12
+ 404
13
+ ),
14
+ FST_ERR_OPTIONS_NOT_OBJ: createError(
15
+ 'FST_ERR_OPTIONS_NOT_OBJ',
16
+ 'Options must be an object',
17
+ 500,
18
+ TypeError
19
+ ),
20
+ FST_ERR_QSP_NOT_FN: createError(
21
+ 'FST_ERR_QSP_NOT_FN',
22
+ "querystringParser option should be a function, instead got '%s'",
23
+ 500,
24
+ TypeError
25
+ ),
26
+ FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN: createError(
27
+ 'FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN',
28
+ "schemaController.bucket option should be a function, instead got '%s'",
29
+ 500,
30
+ TypeError
31
+ ),
32
+ FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN: createError(
33
+ 'FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN',
34
+ "schemaErrorFormatter option should be a non async function. Instead got '%s'.",
35
+ 500,
36
+ TypeError
37
+ ),
38
+ FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ: createError(
39
+ 'FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ',
40
+ "ajv.customOptions option should be an object, instead got '%s'",
41
+ 500,
42
+ TypeError
43
+ ),
44
+ FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR: createError(
45
+ 'FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR',
46
+ "ajv.plugins option should be an array, instead got '%s'",
47
+ 500,
48
+ TypeError
49
+ ),
50
+ FST_ERR_VALIDATION: createError(
51
+ 'FST_ERR_VALIDATION',
52
+ '%s',
53
+ 400
54
+ ),
55
+ FST_ERR_LISTEN_OPTIONS_INVALID: createError(
56
+ 'FST_ERR_LISTEN_OPTIONS_INVALID',
57
+ "Invalid listen options: '%s'",
58
+ 500,
59
+ TypeError
60
+ ),
61
+ FST_ERR_ERROR_HANDLER_NOT_FN: createError(
62
+ 'FST_ERR_ERROR_HANDLER_NOT_FN',
63
+ 'Error Handler must be a function',
64
+ 500,
65
+ TypeError
66
+ ),
67
+ FST_ERR_ERROR_HANDLER_ALREADY_SET: createError(
68
+ 'FST_ERR_ERROR_HANDLER_ALREADY_SET',
69
+ "Error Handler already set in this scope. Set 'allowErrorHandlerOverride: true' to allow overriding.",
70
+ 500,
71
+ TypeError
72
+ ),
73
+
74
+ /**
75
+ * ContentTypeParser
76
+ */
77
+ FST_ERR_CTP_ALREADY_PRESENT: createError(
78
+ 'FST_ERR_CTP_ALREADY_PRESENT',
79
+ "Content type parser '%s' already present."
80
+ ),
81
+ FST_ERR_CTP_INVALID_TYPE: createError(
82
+ 'FST_ERR_CTP_INVALID_TYPE',
83
+ 'The content type should be a string or a RegExp',
84
+ 500,
85
+ TypeError
86
+ ),
87
+ FST_ERR_CTP_EMPTY_TYPE: createError(
88
+ 'FST_ERR_CTP_EMPTY_TYPE',
89
+ 'The content type cannot be an empty string',
90
+ 500,
91
+ TypeError
92
+ ),
93
+ FST_ERR_CTP_INVALID_HANDLER: createError(
94
+ 'FST_ERR_CTP_INVALID_HANDLER',
95
+ 'The content type handler should be a function',
96
+ 500,
97
+ TypeError
98
+ ),
99
+ FST_ERR_CTP_INVALID_PARSE_TYPE: createError(
100
+ 'FST_ERR_CTP_INVALID_PARSE_TYPE',
101
+ "The body parser can only parse your data as 'string' or 'buffer', you asked '%s' which is not supported.",
102
+ 500,
103
+ TypeError
104
+ ),
105
+ FST_ERR_CTP_BODY_TOO_LARGE: createError(
106
+ 'FST_ERR_CTP_BODY_TOO_LARGE',
107
+ 'Request body is too large',
108
+ 413,
109
+ RangeError
110
+ ),
111
+ FST_ERR_CTP_INVALID_MEDIA_TYPE: createError(
112
+ 'FST_ERR_CTP_INVALID_MEDIA_TYPE',
113
+ 'Unsupported Media Type',
114
+ 415
115
+ ),
116
+ FST_ERR_CTP_INVALID_CONTENT_LENGTH: createError(
117
+ 'FST_ERR_CTP_INVALID_CONTENT_LENGTH',
118
+ 'Request body size did not match Content-Length',
119
+ 400,
120
+ RangeError
121
+ ),
122
+ FST_ERR_CTP_EMPTY_JSON_BODY: createError(
123
+ 'FST_ERR_CTP_EMPTY_JSON_BODY',
124
+ "Body cannot be empty when content-type is set to 'application/json'",
125
+ 400
126
+ ),
127
+ FST_ERR_CTP_INVALID_JSON_BODY: createError(
128
+ 'FST_ERR_CTP_INVALID_JSON_BODY',
129
+ "Body is not valid JSON but content-type is set to 'application/json'",
130
+ 400
131
+ ),
132
+ FST_ERR_CTP_INSTANCE_ALREADY_STARTED: createError(
133
+ 'FST_ERR_CTP_INSTANCE_ALREADY_STARTED',
134
+ 'Cannot call "%s" when fastify instance is already started!',
135
+ 400
136
+ ),
137
+
138
+ /**
139
+ * decorate
140
+ */
141
+ FST_ERR_DEC_ALREADY_PRESENT: createError(
142
+ 'FST_ERR_DEC_ALREADY_PRESENT',
143
+ "The decorator '%s' has already been added!"
144
+ ),
145
+ FST_ERR_DEC_DEPENDENCY_INVALID_TYPE: createError(
146
+ 'FST_ERR_DEC_DEPENDENCY_INVALID_TYPE',
147
+ "The dependencies of decorator '%s' must be of type Array.",
148
+ 500,
149
+ TypeError
150
+ ),
151
+ FST_ERR_DEC_MISSING_DEPENDENCY: createError(
152
+ 'FST_ERR_DEC_MISSING_DEPENDENCY',
153
+ "The decorator is missing dependency '%s'."
154
+ ),
155
+ FST_ERR_DEC_AFTER_START: createError(
156
+ 'FST_ERR_DEC_AFTER_START',
157
+ "The decorator '%s' has been added after start!"
158
+ ),
159
+ FST_ERR_DEC_REFERENCE_TYPE: createError(
160
+ 'FST_ERR_DEC_REFERENCE_TYPE',
161
+ "The decorator '%s' of type '%s' is a reference type. Use the { getter, setter } interface instead."
162
+ ),
163
+ FST_ERR_DEC_UNDECLARED: createError(
164
+ 'FST_ERR_DEC_UNDECLARED',
165
+ "No decorator '%s' has been declared on %s."
166
+ ),
167
+
168
+ /**
169
+ * hooks
170
+ */
171
+ FST_ERR_HOOK_INVALID_TYPE: createError(
172
+ 'FST_ERR_HOOK_INVALID_TYPE',
173
+ 'The hook name must be a string',
174
+ 500,
175
+ TypeError
176
+ ),
177
+ FST_ERR_HOOK_INVALID_HANDLER: createError(
178
+ 'FST_ERR_HOOK_INVALID_HANDLER',
179
+ '%s hook should be a function, instead got %s',
180
+ 500,
181
+ TypeError
182
+ ),
183
+ FST_ERR_HOOK_INVALID_ASYNC_HANDLER: createError(
184
+ 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER',
185
+ 'Async function has too many arguments. Async hooks should not use the \'done\' argument.',
186
+ 500,
187
+ TypeError
188
+ ),
189
+ FST_ERR_HOOK_NOT_SUPPORTED: createError(
190
+ 'FST_ERR_HOOK_NOT_SUPPORTED',
191
+ '%s hook not supported!',
192
+ 500,
193
+ TypeError
194
+ ),
195
+
196
+ /**
197
+ * Middlewares
198
+ */
199
+ FST_ERR_MISSING_MIDDLEWARE: createError(
200
+ 'FST_ERR_MISSING_MIDDLEWARE',
201
+ 'You must register a plugin for handling middlewares, visit fastify.dev/docs/latest/Reference/Middleware/ for more info.',
202
+ 500
203
+ ),
204
+
205
+ FST_ERR_HOOK_TIMEOUT: createError(
206
+ 'FST_ERR_HOOK_TIMEOUT',
207
+ "A callback for '%s' hook%s timed out. You may have forgotten to call 'done' function or to resolve a Promise"
208
+ ),
209
+
210
+ /**
211
+ * logger
212
+ */
213
+ FST_ERR_LOG_INVALID_DESTINATION: createError(
214
+ 'FST_ERR_LOG_INVALID_DESTINATION',
215
+ 'Cannot specify both logger.stream and logger.file options'
216
+ ),
217
+
218
+ FST_ERR_LOG_INVALID_LOGGER: createError(
219
+ 'FST_ERR_LOG_INVALID_LOGGER',
220
+ "Invalid logger object provided. The logger instance should have these functions(s): '%s'.",
221
+ 500,
222
+ TypeError
223
+ ),
224
+
225
+ FST_ERR_LOG_INVALID_LOGGER_INSTANCE: createError(
226
+ 'FST_ERR_LOG_INVALID_LOGGER_INSTANCE',
227
+ 'loggerInstance only accepts a logger instance.',
228
+ 500,
229
+ TypeError
230
+ ),
231
+
232
+ FST_ERR_LOG_INVALID_LOGGER_CONFIG: createError(
233
+ 'FST_ERR_LOG_INVALID_LOGGER_CONFIG',
234
+ 'logger options only accepts a configuration object.',
235
+ 500,
236
+ TypeError
237
+ ),
238
+
239
+ FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED: createError(
240
+ 'FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED',
241
+ 'You cannot provide both logger and loggerInstance. Please provide only one.',
242
+ 500,
243
+ TypeError
244
+ ),
245
+
246
+ /**
247
+ * reply
248
+ */
249
+ FST_ERR_REP_INVALID_PAYLOAD_TYPE: createError(
250
+ 'FST_ERR_REP_INVALID_PAYLOAD_TYPE',
251
+ "Attempted to send payload of invalid type '%s'. Expected a string or Buffer.",
252
+ 500,
253
+ TypeError
254
+ ),
255
+ FST_ERR_REP_RESPONSE_BODY_CONSUMED: createError(
256
+ 'FST_ERR_REP_RESPONSE_BODY_CONSUMED',
257
+ 'Response.body is already consumed.'
258
+ ),
259
+ FST_ERR_REP_READABLE_STREAM_LOCKED: createError(
260
+ 'FST_ERR_REP_READABLE_STREAM_LOCKED',
261
+ 'ReadableStream was locked. You should call releaseLock() method on reader before sending.'
262
+ ),
263
+ FST_ERR_REP_ALREADY_SENT: createError(
264
+ 'FST_ERR_REP_ALREADY_SENT',
265
+ 'Reply was already sent, did you forget to "return reply" in "%s" (%s)?'
266
+ ),
267
+ FST_ERR_REP_SENT_VALUE: createError(
268
+ 'FST_ERR_REP_SENT_VALUE',
269
+ 'The only possible value for reply.sent is true.',
270
+ 500,
271
+ TypeError
272
+ ),
273
+ FST_ERR_SEND_INSIDE_ONERR: createError(
274
+ 'FST_ERR_SEND_INSIDE_ONERR',
275
+ 'You cannot use `send` inside the `onError` hook'
276
+ ),
277
+ FST_ERR_SEND_UNDEFINED_ERR: createError(
278
+ 'FST_ERR_SEND_UNDEFINED_ERR',
279
+ 'Undefined error has occurred'
280
+ ),
281
+ FST_ERR_BAD_STATUS_CODE: createError(
282
+ 'FST_ERR_BAD_STATUS_CODE',
283
+ 'Called reply with an invalid status code: %s'
284
+ ),
285
+ FST_ERR_BAD_TRAILER_NAME: createError(
286
+ 'FST_ERR_BAD_TRAILER_NAME',
287
+ 'Called reply.trailer with an invalid header name: %s'
288
+ ),
289
+ FST_ERR_BAD_TRAILER_VALUE: createError(
290
+ 'FST_ERR_BAD_TRAILER_VALUE',
291
+ "Called reply.trailer('%s', fn) with an invalid type: %s. Expected a function."
292
+ ),
293
+ FST_ERR_FAILED_ERROR_SERIALIZATION: createError(
294
+ 'FST_ERR_FAILED_ERROR_SERIALIZATION',
295
+ 'Failed to serialize an error. Error: %s. Original error: %s'
296
+ ),
297
+ FST_ERR_MISSING_SERIALIZATION_FN: createError(
298
+ 'FST_ERR_MISSING_SERIALIZATION_FN',
299
+ 'Missing serialization function. Key "%s"'
300
+ ),
301
+ FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN: createError(
302
+ 'FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN',
303
+ 'Missing serialization function. Key "%s:%s"'
304
+ ),
305
+ FST_ERR_REQ_INVALID_VALIDATION_INVOCATION: createError(
306
+ 'FST_ERR_REQ_INVALID_VALIDATION_INVOCATION',
307
+ 'Invalid validation invocation. Missing validation function for HTTP part "%s" nor schema provided.'
308
+ ),
309
+
310
+ /**
311
+ * schemas
312
+ */
313
+ FST_ERR_SCH_MISSING_ID: createError(
314
+ 'FST_ERR_SCH_MISSING_ID',
315
+ 'Missing schema $id property'
316
+ ),
317
+ FST_ERR_SCH_ALREADY_PRESENT: createError(
318
+ 'FST_ERR_SCH_ALREADY_PRESENT',
319
+ "Schema with id '%s' already declared!"
320
+ ),
321
+ FST_ERR_SCH_CONTENT_MISSING_SCHEMA: createError(
322
+ 'FST_ERR_SCH_CONTENT_MISSING_SCHEMA',
323
+ "Schema is missing for the content type '%s'"
324
+ ),
325
+ FST_ERR_SCH_DUPLICATE: createError(
326
+ 'FST_ERR_SCH_DUPLICATE',
327
+ "Schema with '%s' already present!"
328
+ ),
329
+ FST_ERR_SCH_VALIDATION_BUILD: createError(
330
+ 'FST_ERR_SCH_VALIDATION_BUILD',
331
+ 'Failed building the validation schema for %s: %s, due to error %s'
332
+ ),
333
+ FST_ERR_SCH_SERIALIZATION_BUILD: createError(
334
+ 'FST_ERR_SCH_SERIALIZATION_BUILD',
335
+ 'Failed building the serialization schema for %s: %s, due to error %s'
336
+ ),
337
+ FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX: createError(
338
+ 'FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX',
339
+ 'response schemas should be nested under a valid status code, e.g { 2xx: { type: "object" } }'
340
+ ),
341
+
342
+ /**
343
+ * initialConfig
344
+ */
345
+ FST_ERR_INIT_OPTS_INVALID: createError(
346
+ 'FST_ERR_INIT_OPTS_INVALID',
347
+ "Invalid initialization options: '%s'"
348
+ ),
349
+ FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE: createError(
350
+ 'FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE',
351
+ "Cannot set forceCloseConnections to 'idle' as your HTTP server does not support closeIdleConnections method"
352
+ ),
353
+
354
+ /**
355
+ * router
356
+ */
357
+ FST_ERR_DUPLICATED_ROUTE: createError(
358
+ 'FST_ERR_DUPLICATED_ROUTE',
359
+ "Method '%s' already declared for route '%s'"
360
+ ),
361
+ FST_ERR_BAD_URL: createError(
362
+ 'FST_ERR_BAD_URL',
363
+ "'%s' is not a valid url component",
364
+ 400,
365
+ URIError
366
+ ),
367
+ FST_ERR_ASYNC_CONSTRAINT: createError(
368
+ 'FST_ERR_ASYNC_CONSTRAINT',
369
+ 'Unexpected error from async constraint',
370
+ 500
371
+ ),
372
+ FST_ERR_INVALID_URL: createError(
373
+ 'FST_ERR_INVALID_URL',
374
+ "URL must be a string. Received '%s'",
375
+ 400,
376
+ TypeError
377
+ ),
378
+ FST_ERR_ROUTE_OPTIONS_NOT_OBJ: createError(
379
+ 'FST_ERR_ROUTE_OPTIONS_NOT_OBJ',
380
+ 'Options for "%s:%s" route must be an object',
381
+ 500,
382
+ TypeError
383
+ ),
384
+ FST_ERR_ROUTE_DUPLICATED_HANDLER: createError(
385
+ 'FST_ERR_ROUTE_DUPLICATED_HANDLER',
386
+ 'Duplicate handler for "%s:%s" route is not allowed!',
387
+ 500
388
+ ),
389
+ FST_ERR_ROUTE_HANDLER_NOT_FN: createError(
390
+ 'FST_ERR_ROUTE_HANDLER_NOT_FN',
391
+ 'Error Handler for %s:%s route, if defined, must be a function',
392
+ 500,
393
+ TypeError
394
+ ),
395
+ FST_ERR_ROUTE_MISSING_HANDLER: createError(
396
+ 'FST_ERR_ROUTE_MISSING_HANDLER',
397
+ 'Missing handler function for "%s:%s" route.',
398
+ 500
399
+ ),
400
+ FST_ERR_ROUTE_METHOD_INVALID: createError(
401
+ 'FST_ERR_ROUTE_METHOD_INVALID',
402
+ 'Provided method is invalid!',
403
+ 500,
404
+ TypeError
405
+ ),
406
+ FST_ERR_ROUTE_METHOD_NOT_SUPPORTED: createError(
407
+ 'FST_ERR_ROUTE_METHOD_NOT_SUPPORTED',
408
+ '%s method is not supported.',
409
+ 500
410
+ ),
411
+ FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED: createError(
412
+ 'FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED',
413
+ 'Body validation schema for %s:%s route is not supported!',
414
+ 500
415
+ ),
416
+ FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT: createError(
417
+ 'FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT',
418
+ "'bodyLimit' option must be an integer > 0. Got '%s'",
419
+ 500,
420
+ TypeError
421
+ ),
422
+ FST_ERR_HANDLER_TIMEOUT: createError(
423
+ 'FST_ERR_HANDLER_TIMEOUT',
424
+ "Request timed out after %s ms on route '%s'",
425
+ 503
426
+ ),
427
+ FST_ERR_ROUTE_HANDLER_TIMEOUT_OPTION_NOT_INT: createError(
428
+ 'FST_ERR_ROUTE_HANDLER_TIMEOUT_OPTION_NOT_INT',
429
+ "'handlerTimeout' option must be an integer > 0. Got '%s'",
430
+ 500,
431
+ TypeError
432
+ ),
433
+ FST_ERR_ROUTE_REWRITE_NOT_STR: createError(
434
+ 'FST_ERR_ROUTE_REWRITE_NOT_STR',
435
+ 'Rewrite url for "%s" needs to be of type "string" but received "%s"',
436
+ 500,
437
+ TypeError
438
+ ),
439
+
440
+ /**
441
+ * again listen when close server
442
+ */
443
+ FST_ERR_REOPENED_CLOSE_SERVER: createError(
444
+ 'FST_ERR_REOPENED_CLOSE_SERVER',
445
+ 'Fastify has already been closed and cannot be reopened'
446
+ ),
447
+ FST_ERR_REOPENED_SERVER: createError(
448
+ 'FST_ERR_REOPENED_SERVER',
449
+ 'Fastify is already listening'
450
+ ),
451
+ FST_ERR_INSTANCE_ALREADY_LISTENING: createError(
452
+ 'FST_ERR_INSTANCE_ALREADY_LISTENING',
453
+ 'Fastify instance is already listening. %s'
454
+ ),
455
+
456
+ /**
457
+ * plugin
458
+ */
459
+ FST_ERR_PLUGIN_VERSION_MISMATCH: createError(
460
+ 'FST_ERR_PLUGIN_VERSION_MISMATCH',
461
+ "fastify-plugin: %s - expected '%s' fastify version, '%s' is installed"
462
+ ),
463
+ FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE: createError(
464
+ 'FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE',
465
+ "The decorator '%s'%s is not present in %s"
466
+ ),
467
+ FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER: createError(
468
+ 'FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER',
469
+ 'The %s plugin being registered mixes async and callback styles. Async plugin should not mix async and callback style.',
470
+ 500,
471
+ TypeError
472
+ ),
473
+
474
+ /**
475
+ * Avvio Errors
476
+ */
477
+ FST_ERR_PLUGIN_CALLBACK_NOT_FN: createError(
478
+ 'FST_ERR_PLUGIN_CALLBACK_NOT_FN',
479
+ 'fastify-plugin: %s',
480
+ 500,
481
+ TypeError
482
+ ),
483
+ FST_ERR_PLUGIN_NOT_VALID: createError(
484
+ 'FST_ERR_PLUGIN_NOT_VALID',
485
+ 'fastify-plugin: %s'
486
+ ),
487
+ FST_ERR_ROOT_PLG_BOOTED: createError(
488
+ 'FST_ERR_ROOT_PLG_BOOTED',
489
+ 'fastify-plugin: %s'
490
+ ),
491
+ FST_ERR_PARENT_PLUGIN_BOOTED: createError(
492
+ 'FST_ERR_PARENT_PLUGIN_BOOTED',
493
+ 'fastify-plugin: %s'
494
+ ),
495
+ FST_ERR_PLUGIN_TIMEOUT: createError(
496
+ 'FST_ERR_PLUGIN_TIMEOUT',
497
+ 'fastify-plugin: %s'
498
+ )
499
+ }
500
+
501
+ function appendStackTrace (oldErr, newErr) {
502
+ newErr.cause = oldErr
503
+
504
+ return newErr
505
+ }
506
+
507
+ module.exports = codes
508
+ module.exports.appendStackTrace = appendStackTrace
509
+ module.exports.AVVIO_ERRORS_MAP = {
510
+ AVV_ERR_CALLBACK_NOT_FN: codes.FST_ERR_PLUGIN_CALLBACK_NOT_FN,
511
+ AVV_ERR_PLUGIN_NOT_VALID: codes.FST_ERR_PLUGIN_NOT_VALID,
512
+ AVV_ERR_ROOT_PLG_BOOTED: codes.FST_ERR_ROOT_PLG_BOOTED,
513
+ AVV_ERR_PARENT_PLG_LOADED: codes.FST_ERR_PARENT_PLUGIN_BOOTED,
514
+ AVV_ERR_READY_TIMEOUT: codes.FST_ERR_PLUGIN_TIMEOUT,
515
+ AVV_ERR_PLUGIN_EXEC_TIMEOUT: codes.FST_ERR_PLUGIN_TIMEOUT
516
+ }
@@ -0,0 +1,190 @@
1
+ 'use strict'
2
+
3
+ const FindMyWay = require('find-my-way')
4
+
5
+ const Reply = require('./reply')
6
+ const Request = require('./request')
7
+ const Context = require('./context')
8
+ const {
9
+ kRoutePrefix,
10
+ kCanSetNotFoundHandler,
11
+ kFourOhFourLevelInstance,
12
+ kFourOhFourContext,
13
+ kHooks,
14
+ kErrorHandler
15
+ } = require('./symbols.js')
16
+ const { lifecycleHooks } = require('./hooks')
17
+ const { buildErrorHandler } = require('./error-handler.js')
18
+ const {
19
+ FST_ERR_NOT_FOUND
20
+ } = require('./errors')
21
+ const { createChildLogger } = require('./logger-factory')
22
+ const { getGenReqId } = require('./req-id-gen-factory.js')
23
+
24
+ /**
25
+ * Each fastify instance have a:
26
+ * kFourOhFourLevelInstance: point to a fastify instance that has the 404 handler set
27
+ * kCanSetNotFoundHandler: bool to track if the 404 handler has already been set
28
+ * kFourOhFour: the singleton instance of this 404 module
29
+ * kFourOhFourContext: the context in the reply object where the handler will be executed
30
+ */
31
+ function fourOhFour (options) {
32
+ const { logger, disableRequestLogging } = options
33
+
34
+ // 404 router, used for handling encapsulated 404 handlers
35
+ const router = FindMyWay({ onBadUrl: createOnBadUrl(), defaultRoute: fourOhFourFallBack })
36
+ let _onBadUrlHandler = null
37
+
38
+ return { router, setNotFoundHandler, setContext, arrange404 }
39
+
40
+ function arrange404 (instance) {
41
+ // Change the pointer of the fastify instance to itself, so register + prefix can add new 404 handler
42
+ instance[kFourOhFourLevelInstance] = instance
43
+ instance[kCanSetNotFoundHandler] = true
44
+ // we need to bind instance for the context
45
+ router.onBadUrl = router.onBadUrl.bind(instance)
46
+ router.defaultRoute = router.defaultRoute.bind(instance)
47
+ }
48
+
49
+ function basic404 (request, reply) {
50
+ const { url, method } = request.raw
51
+ const message = `Route ${method}:${url} not found`
52
+ const resolvedDisableRequestLogging = typeof disableRequestLogging === 'function' ? disableRequestLogging(request.raw) : disableRequestLogging
53
+ if (!resolvedDisableRequestLogging) {
54
+ request.log.info(message)
55
+ }
56
+ reply.code(404).send({
57
+ message,
58
+ error: 'Not Found',
59
+ statusCode: 404
60
+ })
61
+ }
62
+
63
+ function createOnBadUrl () {
64
+ return function onBadUrl (path, req, res) {
65
+ const fourOhFourContext = this[kFourOhFourLevelInstance][kFourOhFourContext]
66
+ const id = getGenReqId(fourOhFourContext.server, req)
67
+ const childLogger = createChildLogger(fourOhFourContext, logger, req, id)
68
+ const request = new Request(id, null, req, null, childLogger, fourOhFourContext)
69
+ const reply = new Reply(res, request, childLogger)
70
+
71
+ _onBadUrlHandler(request, reply)
72
+ }
73
+ }
74
+
75
+ function setContext (instance, context) {
76
+ const _404Context = Object.assign({}, instance[kFourOhFourContext])
77
+ _404Context.onSend = context.onSend
78
+ context[kFourOhFourContext] = _404Context
79
+ }
80
+
81
+ function setNotFoundHandler (opts, handler, avvio, routeHandler) {
82
+ // First initialization of the fastify root instance
83
+ if (this[kCanSetNotFoundHandler] === undefined) {
84
+ this[kCanSetNotFoundHandler] = true
85
+ }
86
+ if (this[kFourOhFourContext] === undefined) {
87
+ this[kFourOhFourContext] = null
88
+ }
89
+
90
+ const _fastify = this
91
+ const prefix = this[kRoutePrefix] || '/'
92
+
93
+ if (this[kCanSetNotFoundHandler] === false) {
94
+ throw new Error(`Not found handler already set for Fastify instance with prefix: '${prefix}'`)
95
+ }
96
+
97
+ if (typeof opts === 'object') {
98
+ if (opts.preHandler) {
99
+ if (Array.isArray(opts.preHandler)) {
100
+ opts.preHandler = opts.preHandler.map(hook => hook.bind(_fastify))
101
+ } else {
102
+ opts.preHandler = opts.preHandler.bind(_fastify)
103
+ }
104
+ }
105
+
106
+ if (opts.preValidation) {
107
+ if (Array.isArray(opts.preValidation)) {
108
+ opts.preValidation = opts.preValidation.map(hook => hook.bind(_fastify))
109
+ } else {
110
+ opts.preValidation = opts.preValidation.bind(_fastify)
111
+ }
112
+ }
113
+ }
114
+
115
+ if (typeof opts === 'function') {
116
+ handler = opts
117
+ opts = undefined
118
+ }
119
+ opts = opts || {}
120
+
121
+ if (handler) {
122
+ this[kFourOhFourLevelInstance][kCanSetNotFoundHandler] = false
123
+ handler = handler.bind(this)
124
+ // update onBadUrl handler
125
+ _onBadUrlHandler = handler
126
+ } else {
127
+ handler = basic404
128
+ // update onBadUrl handler
129
+ _onBadUrlHandler = basic404
130
+ }
131
+
132
+ this.after((notHandledErr, done) => {
133
+ _setNotFoundHandler.call(this, prefix, opts, handler, avvio, routeHandler)
134
+ done(notHandledErr)
135
+ })
136
+ }
137
+
138
+ function _setNotFoundHandler (prefix, opts, handler, avvio, routeHandler) {
139
+ const context = new Context({
140
+ schema: opts.schema,
141
+ handler,
142
+ config: opts.config || {},
143
+ server: this
144
+ })
145
+
146
+ avvio.once('preReady', () => {
147
+ const context = this[kFourOhFourContext]
148
+ for (const hook of lifecycleHooks) {
149
+ const toSet = this[kHooks][hook]
150
+ .concat(opts[hook] || [])
151
+ .map(h => h.bind(this))
152
+ context[hook] = toSet.length ? toSet : null
153
+ }
154
+ context.errorHandler = opts.errorHandler
155
+ ? buildErrorHandler(this[kErrorHandler], opts.errorHandler)
156
+ : this[kErrorHandler]
157
+ })
158
+
159
+ if (this[kFourOhFourContext] !== null && prefix === '/') {
160
+ Object.assign(this[kFourOhFourContext], context) // Replace the default 404 handler
161
+ return
162
+ }
163
+
164
+ this[kFourOhFourLevelInstance][kFourOhFourContext] = context
165
+
166
+ router.all(prefix + (prefix.endsWith('/') ? '*' : '/*'), routeHandler, context)
167
+ router.all(prefix, routeHandler, context)
168
+ }
169
+
170
+ function fourOhFourFallBack (req, res) {
171
+ // if this happen, we have a very bad bug
172
+ // we might want to do some hard debugging
173
+ // here, let's print out as much info as
174
+ // we can
175
+ const fourOhFourContext = this[kFourOhFourLevelInstance][kFourOhFourContext]
176
+ const id = getGenReqId(fourOhFourContext.server, req)
177
+ const childLogger = createChildLogger(fourOhFourContext, logger, req, id)
178
+
179
+ childLogger.info({ req }, 'incoming request')
180
+
181
+ const request = new Request(id, null, req, null, childLogger, fourOhFourContext)
182
+ const reply = new Reply(res, request, childLogger)
183
+
184
+ request.log.warn('the default handler for 404 did not catch this, this is likely a fastify bug, please report it')
185
+ request.log.warn(router.prettyPrint())
186
+ reply.code(404).send(new FST_ERR_NOT_FOUND())
187
+ }
188
+ }
189
+
190
+ module.exports = fourOhFour