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.
- package/.borp.yaml +3 -0
- package/.markdownlint-cli2.yaml +22 -0
- package/.prettierignore +1 -0
- package/GOVERNANCE.md +4 -0
- package/LICENSE +21 -0
- package/PROJECT_CHARTER.md +126 -0
- package/README.md +423 -0
- package/SECURITY.md +220 -0
- package/SPONSORS.md +24 -0
- package/build/build-error-serializer.js +35 -0
- package/build/build-validation.js +169 -0
- package/build/sync-version.js +11 -0
- package/docs/Guides/Benchmarking.md +60 -0
- package/docs/Guides/Database.md +321 -0
- package/docs/Guides/Delay-Accepting-Requests.md +608 -0
- package/docs/Guides/Detecting-When-Clients-Abort.md +172 -0
- package/docs/Guides/Ecosystem.md +726 -0
- package/docs/Guides/Fluent-Schema.md +127 -0
- package/docs/Guides/Getting-Started.md +620 -0
- package/docs/Guides/Index.md +43 -0
- package/docs/Guides/Migration-Guide-V3.md +287 -0
- package/docs/Guides/Migration-Guide-V4.md +267 -0
- package/docs/Guides/Migration-Guide-V5.md +727 -0
- package/docs/Guides/Plugins-Guide.md +520 -0
- package/docs/Guides/Prototype-Poisoning.md +383 -0
- package/docs/Guides/Recommendations.md +378 -0
- package/docs/Guides/Serverless.md +604 -0
- package/docs/Guides/Style-Guide.md +246 -0
- package/docs/Guides/Testing.md +481 -0
- package/docs/Guides/Write-Plugin.md +103 -0
- package/docs/Guides/Write-Type-Provider.md +34 -0
- package/docs/Reference/ContentTypeParser.md +271 -0
- package/docs/Reference/Decorators.md +436 -0
- package/docs/Reference/Encapsulation.md +194 -0
- package/docs/Reference/Errors.md +377 -0
- package/docs/Reference/HTTP2.md +94 -0
- package/docs/Reference/Hooks.md +958 -0
- package/docs/Reference/Index.md +73 -0
- package/docs/Reference/LTS.md +86 -0
- package/docs/Reference/Lifecycle.md +99 -0
- package/docs/Reference/Logging.md +268 -0
- package/docs/Reference/Middleware.md +79 -0
- package/docs/Reference/Plugins.md +245 -0
- package/docs/Reference/Principles.md +73 -0
- package/docs/Reference/Reply.md +1001 -0
- package/docs/Reference/Request.md +295 -0
- package/docs/Reference/Routes.md +802 -0
- package/docs/Reference/Server.md +2389 -0
- package/docs/Reference/Type-Providers.md +256 -0
- package/docs/Reference/TypeScript.md +1729 -0
- package/docs/Reference/Validation-and-Serialization.md +1130 -0
- package/docs/Reference/Warnings.md +58 -0
- package/docs/index.md +24 -0
- package/docs/resources/encapsulation_context.drawio +1 -0
- package/docs/resources/encapsulation_context.svg +3 -0
- package/eslint.config.js +35 -0
- package/examples/asyncawait.js +38 -0
- package/examples/benchmark/body.json +3 -0
- package/examples/benchmark/hooks-benchmark-async-await.js +44 -0
- package/examples/benchmark/hooks-benchmark.js +52 -0
- package/examples/benchmark/parser.js +47 -0
- package/examples/benchmark/simple.js +30 -0
- package/examples/benchmark/webstream.js +27 -0
- package/examples/hooks.js +91 -0
- package/examples/http2.js +39 -0
- package/examples/https.js +38 -0
- package/examples/parser.js +53 -0
- package/examples/plugin.js +12 -0
- package/examples/route-prefix.js +38 -0
- package/examples/shared-schema.js +38 -0
- package/examples/simple-stream.js +20 -0
- package/examples/simple.js +32 -0
- package/examples/simple.mjs +27 -0
- package/examples/typescript-server.ts +79 -0
- package/examples/use-plugin.js +29 -0
- package/fastify.d.ts +253 -0
- package/fastify.js +985 -0
- package/integration/server.js +29 -0
- package/integration/test.sh +23 -0
- package/lib/config-validator.js +1266 -0
- package/lib/content-type-parser.js +413 -0
- package/lib/content-type.js +160 -0
- package/lib/context.js +98 -0
- package/lib/decorate.js +152 -0
- package/lib/error-handler.js +173 -0
- package/lib/error-serializer.js +134 -0
- package/lib/error-status.js +14 -0
- package/lib/errors.js +516 -0
- package/lib/four-oh-four.js +190 -0
- package/lib/handle-request.js +195 -0
- package/lib/head-route.js +45 -0
- package/lib/hooks.js +429 -0
- package/lib/initial-config-validation.js +37 -0
- package/lib/logger-factory.js +136 -0
- package/lib/logger-pino.js +68 -0
- package/lib/noop-set.js +10 -0
- package/lib/plugin-override.js +90 -0
- package/lib/plugin-utils.js +169 -0
- package/lib/promise.js +23 -0
- package/lib/reply.js +1030 -0
- package/lib/req-id-gen-factory.js +52 -0
- package/lib/request.js +391 -0
- package/lib/route.js +686 -0
- package/lib/schema-controller.js +164 -0
- package/lib/schemas.js +207 -0
- package/lib/server.js +441 -0
- package/lib/symbols.js +71 -0
- package/lib/validation.js +280 -0
- package/lib/warnings.js +57 -0
- package/lib/wrap-thenable.js +84 -0
- package/package.json +225 -0
- package/scripts/validate-ecosystem-links.js +179 -0
- package/test/404s.test.js +2035 -0
- package/test/500s.test.js +422 -0
- package/test/allow-unsafe-regex.test.js +92 -0
- package/test/als.test.js +65 -0
- package/test/async-await.test.js +705 -0
- package/test/async-dispose.test.js +20 -0
- package/test/async_hooks.test.js +52 -0
- package/test/body-limit.test.js +224 -0
- package/test/buffer.test.js +74 -0
- package/test/build/error-serializer.test.js +36 -0
- package/test/build/version.test.js +14 -0
- package/test/build-certificate.js +109 -0
- package/test/bundler/README.md +29 -0
- package/test/bundler/esbuild/bundler-test.js +32 -0
- package/test/bundler/esbuild/package.json +10 -0
- package/test/bundler/esbuild/src/fail-plugin-version.js +14 -0
- package/test/bundler/esbuild/src/index.js +9 -0
- package/test/bundler/webpack/bundler-test.js +32 -0
- package/test/bundler/webpack/package.json +11 -0
- package/test/bundler/webpack/src/fail-plugin-version.js +14 -0
- package/test/bundler/webpack/src/index.js +9 -0
- package/test/bundler/webpack/webpack.config.js +15 -0
- package/test/case-insensitive.test.js +102 -0
- package/test/chainable.test.js +40 -0
- package/test/child-logger-factory.test.js +128 -0
- package/test/client-timeout.test.js +38 -0
- package/test/close-pipelining.test.js +78 -0
- package/test/close.test.js +706 -0
- package/test/conditional-pino.test.js +47 -0
- package/test/connection-timeout.test.js +42 -0
- package/test/constrained-routes.test.js +1138 -0
- package/test/content-length.test.js +174 -0
- package/test/content-parser.test.js +739 -0
- package/test/content-type.test.js +181 -0
- package/test/context-config.test.js +164 -0
- package/test/custom-http-server.test.js +118 -0
- package/test/custom-parser-async.test.js +59 -0
- package/test/custom-parser.0.test.js +701 -0
- package/test/custom-parser.1.test.js +266 -0
- package/test/custom-parser.2.test.js +91 -0
- package/test/custom-parser.3.test.js +208 -0
- package/test/custom-parser.4.test.js +218 -0
- package/test/custom-parser.5.test.js +130 -0
- package/test/custom-querystring-parser.test.js +129 -0
- package/test/decorator.test.js +1330 -0
- package/test/delete.test.js +344 -0
- package/test/diagnostics-channel/404.test.js +49 -0
- package/test/diagnostics-channel/async-delay-request.test.js +65 -0
- package/test/diagnostics-channel/async-request.test.js +64 -0
- package/test/diagnostics-channel/error-before-handler.test.js +35 -0
- package/test/diagnostics-channel/error-request.test.js +53 -0
- package/test/diagnostics-channel/error-status.test.js +123 -0
- package/test/diagnostics-channel/init.test.js +50 -0
- package/test/diagnostics-channel/sync-delay-request.test.js +49 -0
- package/test/diagnostics-channel/sync-request-reply.test.js +51 -0
- package/test/diagnostics-channel/sync-request.test.js +54 -0
- package/test/encapsulated-child-logger-factory.test.js +69 -0
- package/test/encapsulated-error-handler.test.js +237 -0
- package/test/esm/errorCodes.test.mjs +10 -0
- package/test/esm/esm.test.mjs +13 -0
- package/test/esm/index.test.js +8 -0
- package/test/esm/named-exports.mjs +14 -0
- package/test/esm/other.mjs +8 -0
- package/test/esm/plugin.mjs +8 -0
- package/test/fastify-instance.test.js +300 -0
- package/test/find-route.test.js +152 -0
- package/test/fluent-schema.test.js +209 -0
- package/test/genReqId.test.js +426 -0
- package/test/handler-context.test.js +45 -0
- package/test/handler-timeout.test.js +367 -0
- package/test/has-route.test.js +88 -0
- package/test/header-overflow.test.js +55 -0
- package/test/helper.js +496 -0
- package/test/hooks-async.test.js +1099 -0
- package/test/hooks.on-listen.test.js +1162 -0
- package/test/hooks.on-ready.test.js +421 -0
- package/test/hooks.test.js +3578 -0
- package/test/http-methods/copy.test.js +35 -0
- package/test/http-methods/custom-http-methods.test.js +114 -0
- package/test/http-methods/get.test.js +412 -0
- package/test/http-methods/head.test.js +263 -0
- package/test/http-methods/lock.test.js +108 -0
- package/test/http-methods/mkcalendar.test.js +143 -0
- package/test/http-methods/mkcol.test.js +35 -0
- package/test/http-methods/move.test.js +42 -0
- package/test/http-methods/propfind.test.js +136 -0
- package/test/http-methods/proppatch.test.js +105 -0
- package/test/http-methods/report.test.js +142 -0
- package/test/http-methods/search.test.js +233 -0
- package/test/http-methods/trace.test.js +21 -0
- package/test/http-methods/unlock.test.js +38 -0
- package/test/http2/closing.test.js +270 -0
- package/test/http2/constraint.test.js +109 -0
- package/test/http2/head.test.js +34 -0
- package/test/http2/plain.test.js +68 -0
- package/test/http2/secure-with-fallback.test.js +113 -0
- package/test/http2/secure.test.js +67 -0
- package/test/http2/unknown-http-method.test.js +34 -0
- package/test/https/custom-https-server.test.js +58 -0
- package/test/https/https.test.js +136 -0
- package/test/imports.test.js +17 -0
- package/test/inject.test.js +502 -0
- package/test/input-validation.js +335 -0
- package/test/internals/all.test.js +38 -0
- package/test/internals/content-type-parser.test.js +111 -0
- package/test/internals/context.test.js +31 -0
- package/test/internals/decorator.test.js +156 -0
- package/test/internals/errors.test.js +982 -0
- package/test/internals/handle-request.test.js +270 -0
- package/test/internals/hook-runner.test.js +449 -0
- package/test/internals/hooks.test.js +96 -0
- package/test/internals/initial-config.test.js +383 -0
- package/test/internals/logger.test.js +163 -0
- package/test/internals/plugin.test.js +170 -0
- package/test/internals/promise.test.js +63 -0
- package/test/internals/reply-serialize.test.js +714 -0
- package/test/internals/reply.test.js +1920 -0
- package/test/internals/req-id-gen-factory.test.js +133 -0
- package/test/internals/request-validate.test.js +1402 -0
- package/test/internals/request.test.js +506 -0
- package/test/internals/schema-controller-perf.test.js +40 -0
- package/test/internals/server.test.js +91 -0
- package/test/internals/validation.test.js +352 -0
- package/test/issue-4959.test.js +118 -0
- package/test/keep-alive-timeout.test.js +42 -0
- package/test/listen.1.test.js +154 -0
- package/test/listen.2.test.js +113 -0
- package/test/listen.3.test.js +83 -0
- package/test/listen.4.test.js +168 -0
- package/test/listen.5.test.js +122 -0
- package/test/logger/instantiation.test.js +341 -0
- package/test/logger/logger-test-utils.js +47 -0
- package/test/logger/logging.test.js +460 -0
- package/test/logger/options.test.js +579 -0
- package/test/logger/request.test.js +292 -0
- package/test/logger/response.test.js +183 -0
- package/test/logger/tap-parallel-not-ok +0 -0
- package/test/max-requests-per-socket.test.js +113 -0
- package/test/middleware.test.js +37 -0
- package/test/noop-set.test.js +19 -0
- package/test/nullable-validation.test.js +187 -0
- package/test/options.error-handler.test.js +5 -0
- package/test/options.test.js +5 -0
- package/test/output-validation.test.js +140 -0
- package/test/patch.error-handler.test.js +5 -0
- package/test/patch.test.js +5 -0
- package/test/plugin.1.test.js +230 -0
- package/test/plugin.2.test.js +314 -0
- package/test/plugin.3.test.js +287 -0
- package/test/plugin.4.test.js +504 -0
- package/test/plugin.helper.js +8 -0
- package/test/plugin.name.display.js +10 -0
- package/test/post-empty-body.test.js +38 -0
- package/test/pretty-print.test.js +366 -0
- package/test/promises.test.js +125 -0
- package/test/proto-poisoning.test.js +145 -0
- package/test/put.error-handler.test.js +5 -0
- package/test/put.test.js +5 -0
- package/test/register.test.js +184 -0
- package/test/reply-code.test.js +148 -0
- package/test/reply-early-hints.test.js +100 -0
- package/test/reply-error.test.js +815 -0
- package/test/reply-trailers.test.js +445 -0
- package/test/reply-web-stream-locked.test.js +37 -0
- package/test/request-error.test.js +624 -0
- package/test/request-header-host.test.js +339 -0
- package/test/request-id.test.js +118 -0
- package/test/request-timeout.test.js +53 -0
- package/test/route-hooks.test.js +635 -0
- package/test/route-prefix.test.js +904 -0
- package/test/route-shorthand.test.js +48 -0
- package/test/route.1.test.js +259 -0
- package/test/route.2.test.js +100 -0
- package/test/route.3.test.js +213 -0
- package/test/route.4.test.js +127 -0
- package/test/route.5.test.js +211 -0
- package/test/route.6.test.js +306 -0
- package/test/route.7.test.js +406 -0
- package/test/route.8.test.js +225 -0
- package/test/router-options.test.js +1108 -0
- package/test/same-shape.test.js +124 -0
- package/test/schema-examples.test.js +661 -0
- package/test/schema-feature.test.js +2198 -0
- package/test/schema-serialization.test.js +1171 -0
- package/test/schema-special-usage.test.js +1348 -0
- package/test/schema-validation.test.js +1572 -0
- package/test/scripts/validate-ecosystem-links.test.js +339 -0
- package/test/serialize-response.test.js +186 -0
- package/test/server.test.js +347 -0
- package/test/set-error-handler.test.js +69 -0
- package/test/skip-reply-send.test.js +317 -0
- package/test/stream-serializers.test.js +40 -0
- package/test/stream.1.test.js +94 -0
- package/test/stream.2.test.js +129 -0
- package/test/stream.3.test.js +198 -0
- package/test/stream.4.test.js +176 -0
- package/test/stream.5.test.js +188 -0
- package/test/sync-routes.test.js +32 -0
- package/test/throw.test.js +359 -0
- package/test/toolkit.js +63 -0
- package/test/trust-proxy.test.js +162 -0
- package/test/type-provider.test.js +22 -0
- package/test/types/content-type-parser.test-d.ts +72 -0
- package/test/types/decorate-request-reply.test-d.ts +18 -0
- package/test/types/dummy-plugin.ts +9 -0
- package/test/types/errors.test-d.ts +90 -0
- package/test/types/fastify.test-d.ts +352 -0
- package/test/types/hooks.test-d.ts +550 -0
- package/test/types/import.ts +2 -0
- package/test/types/instance.test-d.ts +588 -0
- package/test/types/logger.test-d.ts +277 -0
- package/test/types/plugin.test-d.ts +97 -0
- package/test/types/register.test-d.ts +237 -0
- package/test/types/reply.test-d.ts +254 -0
- package/test/types/request.test-d.ts +188 -0
- package/test/types/route.test-d.ts +553 -0
- package/test/types/schema.test-d.ts +135 -0
- package/test/types/serverFactory.test-d.ts +37 -0
- package/test/types/type-provider.test-d.ts +1213 -0
- package/test/types/using.test-d.ts +17 -0
- package/test/upgrade.test.js +52 -0
- package/test/url-rewriting.test.js +122 -0
- package/test/use-semicolon-delimiter.test.js +168 -0
- package/test/validation-error-handling.test.js +900 -0
- package/test/versioned-routes.test.js +603 -0
- package/test/web-api.test.js +616 -0
- package/test/wrap-thenable.test.js +30 -0
- package/types/content-type-parser.d.ts +75 -0
- package/types/context.d.ts +22 -0
- package/types/errors.d.ts +92 -0
- package/types/hooks.d.ts +875 -0
- package/types/instance.d.ts +609 -0
- package/types/logger.d.ts +107 -0
- package/types/plugin.d.ts +44 -0
- package/types/register.d.ts +42 -0
- package/types/reply.d.ts +81 -0
- package/types/request.d.ts +95 -0
- package/types/route.d.ts +199 -0
- package/types/schema.d.ts +61 -0
- package/types/server-factory.d.ts +19 -0
- package/types/type-provider.d.ts +130 -0
- package/types/utils.d.ts +98 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const stream = require('node:stream')
|
|
4
|
+
|
|
5
|
+
const t = require('node:test')
|
|
6
|
+
const split = require('split2')
|
|
7
|
+
const pino = require('pino')
|
|
8
|
+
|
|
9
|
+
const Fastify = require('../../fastify')
|
|
10
|
+
const helper = require('../helper')
|
|
11
|
+
const { once, on } = stream
|
|
12
|
+
const { request } = require('./logger-test-utils')
|
|
13
|
+
const { partialDeepStrictEqual } = require('../toolkit')
|
|
14
|
+
|
|
15
|
+
t.test('logging', { timeout: 60000 }, async (t) => {
|
|
16
|
+
let localhost
|
|
17
|
+
let localhostForURL
|
|
18
|
+
|
|
19
|
+
t.plan(14)
|
|
20
|
+
|
|
21
|
+
t.before(async function () {
|
|
22
|
+
[localhost, localhostForURL] = await helper.getLoopbackHost()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
await t.test('The default 404 handler logs the incoming request', async (t) => {
|
|
26
|
+
const lines = ['incoming request', 'Route GET:/not-found not found', 'request completed']
|
|
27
|
+
t.plan(lines.length + 1)
|
|
28
|
+
|
|
29
|
+
const stream = split(JSON.parse)
|
|
30
|
+
|
|
31
|
+
const loggerInstance = pino({ level: 'trace' }, stream)
|
|
32
|
+
|
|
33
|
+
const fastify = Fastify({
|
|
34
|
+
loggerInstance
|
|
35
|
+
})
|
|
36
|
+
t.after(() => fastify.close())
|
|
37
|
+
|
|
38
|
+
await fastify.ready()
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
const response = await fastify.inject({ method: 'GET', url: '/not-found' })
|
|
42
|
+
t.assert.strictEqual(response.statusCode, 404)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for await (const [line] of on(stream, 'data')) {
|
|
46
|
+
t.assert.strictEqual(line.msg, lines.shift())
|
|
47
|
+
if (lines.length === 0) break
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
await t.test('should not rely on raw request to log errors', async (t) => {
|
|
52
|
+
const stream = split(JSON.parse)
|
|
53
|
+
const fastify = Fastify({
|
|
54
|
+
logger: {
|
|
55
|
+
stream,
|
|
56
|
+
level: 'info'
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
t.after(() => fastify.close())
|
|
60
|
+
fastify.get('/error', function (req, reply) {
|
|
61
|
+
t.assert.ok(req.log)
|
|
62
|
+
reply.status(415).send(new Error('something happened'))
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
await fastify.ready()
|
|
66
|
+
const server = await fastify.listen({ port: 0, host: localhost })
|
|
67
|
+
const lines = [
|
|
68
|
+
{ msg: `Server listening at ${server}` },
|
|
69
|
+
{ level: 30, msg: 'incoming request' },
|
|
70
|
+
{ res: { statusCode: 415 }, msg: 'something happened' },
|
|
71
|
+
{ res: { statusCode: 415 }, msg: 'request completed' }
|
|
72
|
+
]
|
|
73
|
+
t.plan(lines.length + 1)
|
|
74
|
+
|
|
75
|
+
await request(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
76
|
+
|
|
77
|
+
for await (const [line] of on(stream, 'data')) {
|
|
78
|
+
t.assert.ok(partialDeepStrictEqual(line, lines.shift()))
|
|
79
|
+
if (lines.length === 0) break
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
await t.test('should log the error if no error handler is defined', async (t) => {
|
|
84
|
+
const stream = split(JSON.parse)
|
|
85
|
+
const fastify = Fastify({
|
|
86
|
+
logger: {
|
|
87
|
+
stream,
|
|
88
|
+
level: 'info'
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
t.after(() => fastify.close())
|
|
92
|
+
|
|
93
|
+
fastify.get('/error', function (req, reply) {
|
|
94
|
+
t.assert.ok(req.log)
|
|
95
|
+
reply.send(new Error('a generic error'))
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
await fastify.ready()
|
|
99
|
+
const server = await fastify.listen({ port: 0, host: localhost })
|
|
100
|
+
const lines = [
|
|
101
|
+
{ msg: `Server listening at ${server}` },
|
|
102
|
+
{ msg: 'incoming request' },
|
|
103
|
+
{ level: 50, msg: 'a generic error' },
|
|
104
|
+
{ res: { statusCode: 500 }, msg: 'request completed' }
|
|
105
|
+
]
|
|
106
|
+
t.plan(lines.length + 1)
|
|
107
|
+
|
|
108
|
+
await request(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
109
|
+
|
|
110
|
+
for await (const [line] of on(stream, 'data')) {
|
|
111
|
+
t.assert.ok(partialDeepStrictEqual(line, lines.shift()))
|
|
112
|
+
if (lines.length === 0) break
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
await t.test('should log as info if error status code >= 400 and < 500 if no error handler is defined', async (t) => {
|
|
117
|
+
const stream = split(JSON.parse)
|
|
118
|
+
const fastify = Fastify({
|
|
119
|
+
logger: {
|
|
120
|
+
stream,
|
|
121
|
+
level: 'info'
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
t.after(() => fastify.close())
|
|
125
|
+
|
|
126
|
+
fastify.get('/400', function (req, reply) {
|
|
127
|
+
t.assert.ok(req.log)
|
|
128
|
+
reply.send(Object.assign(new Error('a 400 error'), { statusCode: 400 }))
|
|
129
|
+
})
|
|
130
|
+
fastify.get('/503', function (req, reply) {
|
|
131
|
+
t.assert.ok(req.log)
|
|
132
|
+
reply.send(Object.assign(new Error('a 503 error'), { statusCode: 503 }))
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
await fastify.ready()
|
|
136
|
+
const server = await fastify.listen({ port: 0, host: localhost })
|
|
137
|
+
const lines = [
|
|
138
|
+
{ msg: `Server listening at ${server}` },
|
|
139
|
+
{ msg: 'incoming request' },
|
|
140
|
+
{ level: 30, msg: 'a 400 error' },
|
|
141
|
+
{ res: { statusCode: 400 }, msg: 'request completed' }
|
|
142
|
+
]
|
|
143
|
+
t.plan(lines.length + 1)
|
|
144
|
+
|
|
145
|
+
await request(`http://${localhostForURL}:` + fastify.server.address().port + '/400')
|
|
146
|
+
|
|
147
|
+
for await (const [line] of on(stream, 'data')) {
|
|
148
|
+
t.assert.ok(partialDeepStrictEqual(line, lines.shift()))
|
|
149
|
+
if (lines.length === 0) break
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
await t.test('should log as error if error status code >= 500 if no error handler is defined', async (t) => {
|
|
154
|
+
const stream = split(JSON.parse)
|
|
155
|
+
const fastify = Fastify({
|
|
156
|
+
logger: {
|
|
157
|
+
stream,
|
|
158
|
+
level: 'info'
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
t.after(() => fastify.close())
|
|
162
|
+
fastify.get('/503', function (req, reply) {
|
|
163
|
+
t.assert.ok(req.log)
|
|
164
|
+
reply.send(Object.assign(new Error('a 503 error'), { statusCode: 503 }))
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
await fastify.ready()
|
|
168
|
+
const server = await fastify.listen({ port: 0, host: localhost })
|
|
169
|
+
const lines = [
|
|
170
|
+
{ msg: `Server listening at ${server}` },
|
|
171
|
+
{ msg: 'incoming request' },
|
|
172
|
+
{ level: 50, msg: 'a 503 error' },
|
|
173
|
+
{ res: { statusCode: 503 }, msg: 'request completed' }
|
|
174
|
+
]
|
|
175
|
+
t.plan(lines.length + 1)
|
|
176
|
+
|
|
177
|
+
await request(`http://${localhostForURL}:` + fastify.server.address().port + '/503')
|
|
178
|
+
|
|
179
|
+
for await (const [line] of on(stream, 'data')) {
|
|
180
|
+
t.assert.ok(partialDeepStrictEqual(line, lines.shift()))
|
|
181
|
+
if (lines.length === 0) break
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
await t.test('should not log the error if error handler is defined and it does not error', async (t) => {
|
|
186
|
+
const stream = split(JSON.parse)
|
|
187
|
+
const fastify = Fastify({
|
|
188
|
+
logger: {
|
|
189
|
+
stream,
|
|
190
|
+
level: 'info'
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
t.after(() => fastify.close())
|
|
194
|
+
fastify.get('/error', function (req, reply) {
|
|
195
|
+
t.assert.ok(req.log)
|
|
196
|
+
reply.send(new Error('something happened'))
|
|
197
|
+
})
|
|
198
|
+
fastify.setErrorHandler((err, req, reply) => {
|
|
199
|
+
t.assert.ok(err)
|
|
200
|
+
reply.send('something bad happened')
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
await fastify.ready()
|
|
204
|
+
const server = await fastify.listen({ port: 0, host: localhost })
|
|
205
|
+
const lines = [
|
|
206
|
+
{ msg: `Server listening at ${server}` },
|
|
207
|
+
{ level: 30, msg: 'incoming request' },
|
|
208
|
+
{ res: { statusCode: 200 }, msg: 'request completed' }
|
|
209
|
+
]
|
|
210
|
+
t.plan(lines.length + 2)
|
|
211
|
+
|
|
212
|
+
await request(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
213
|
+
|
|
214
|
+
for await (const [line] of on(stream, 'data')) {
|
|
215
|
+
t.assert.ok(partialDeepStrictEqual(line, lines.shift()))
|
|
216
|
+
if (lines.length === 0) break
|
|
217
|
+
}
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
await t.test('reply.send logs an error if called twice in a row', async (t) => {
|
|
221
|
+
const lines = [
|
|
222
|
+
'incoming request',
|
|
223
|
+
'request completed',
|
|
224
|
+
'Reply was already sent, did you forget to "return reply" in "/" (GET)?',
|
|
225
|
+
'Reply was already sent, did you forget to "return reply" in "/" (GET)?'
|
|
226
|
+
]
|
|
227
|
+
t.plan(lines.length + 1)
|
|
228
|
+
|
|
229
|
+
const stream = split(JSON.parse)
|
|
230
|
+
const loggerInstance = pino(stream)
|
|
231
|
+
|
|
232
|
+
const fastify = Fastify({
|
|
233
|
+
loggerInstance
|
|
234
|
+
})
|
|
235
|
+
t.after(() => fastify.close())
|
|
236
|
+
|
|
237
|
+
fastify.get('/', (req, reply) => {
|
|
238
|
+
reply.send({ hello: 'world' })
|
|
239
|
+
reply.send({ hello: 'world2' })
|
|
240
|
+
reply.send({ hello: 'world3' })
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
244
|
+
const body = await response.json()
|
|
245
|
+
t.assert.ok(partialDeepStrictEqual(body, { hello: 'world' }))
|
|
246
|
+
|
|
247
|
+
for await (const [line] of on(stream, 'data')) {
|
|
248
|
+
t.assert.strictEqual(line.msg, lines.shift())
|
|
249
|
+
if (lines.length === 0) break
|
|
250
|
+
}
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
await t.test('should not log incoming request and outgoing response when disabled', async (t) => {
|
|
254
|
+
t.plan(1)
|
|
255
|
+
const stream = split(JSON.parse)
|
|
256
|
+
const fastify = Fastify({ disableRequestLogging: true, logger: { level: 'info', stream } })
|
|
257
|
+
t.after(() => fastify.close())
|
|
258
|
+
|
|
259
|
+
fastify.get('/500', (req, reply) => {
|
|
260
|
+
reply.code(500).send(Error('500 error'))
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
await fastify.ready()
|
|
264
|
+
|
|
265
|
+
await fastify.inject({ method: 'GET', url: '/500' })
|
|
266
|
+
|
|
267
|
+
// no more readable data
|
|
268
|
+
t.assert.strictEqual(stream.readableLength, 0)
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
await t.test('should not log incoming request, outgoing response and route not found for 404 onBadUrl when disabled', async (t) => {
|
|
272
|
+
t.plan(1)
|
|
273
|
+
const stream = split(JSON.parse)
|
|
274
|
+
const fastify = Fastify({ disableRequestLogging: true, logger: { level: 'info', stream } })
|
|
275
|
+
t.after(() => fastify.close())
|
|
276
|
+
|
|
277
|
+
await fastify.ready()
|
|
278
|
+
|
|
279
|
+
await fastify.inject({ method: 'GET', url: '/%c0' })
|
|
280
|
+
|
|
281
|
+
// no more readable data
|
|
282
|
+
t.assert.strictEqual(stream.readableLength, 0)
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
await t.test('should log incoming request and outgoing response based on disableRequestLogging function', async (t) => {
|
|
286
|
+
const lines = [
|
|
287
|
+
'incoming request',
|
|
288
|
+
'request completed'
|
|
289
|
+
]
|
|
290
|
+
t.plan(lines.length)
|
|
291
|
+
|
|
292
|
+
const stream = split(JSON.parse)
|
|
293
|
+
const loggerInstance = pino(stream)
|
|
294
|
+
|
|
295
|
+
const fastify = Fastify({
|
|
296
|
+
disableRequestLogging: (request) => {
|
|
297
|
+
return request.url !== '/not-logged'
|
|
298
|
+
},
|
|
299
|
+
loggerInstance
|
|
300
|
+
})
|
|
301
|
+
t.after(() => fastify.close())
|
|
302
|
+
|
|
303
|
+
fastify.get('/logged', (req, reply) => {
|
|
304
|
+
return reply.code(200).send({})
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
fastify.get('/not-logged', (req, reply) => {
|
|
308
|
+
return reply.code(200).send({})
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
await fastify.ready()
|
|
312
|
+
|
|
313
|
+
await fastify.inject({ method: 'GET', url: '/not-logged' })
|
|
314
|
+
await fastify.inject({ method: 'GET', url: '/logged' })
|
|
315
|
+
|
|
316
|
+
for await (const [line] of on(stream, 'data')) {
|
|
317
|
+
t.assert.strictEqual(line.msg, lines.shift())
|
|
318
|
+
if (lines.length === 0) break
|
|
319
|
+
}
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
await t.test('defaults to info level', async (t) => {
|
|
323
|
+
const lines = [
|
|
324
|
+
{ req: { method: 'GET' }, msg: 'incoming request' },
|
|
325
|
+
{ res: { statusCode: 200 }, msg: 'request completed' }
|
|
326
|
+
]
|
|
327
|
+
t.plan(lines.length * 2 + 1)
|
|
328
|
+
const stream = split(JSON.parse)
|
|
329
|
+
const fastify = Fastify({
|
|
330
|
+
logger: {
|
|
331
|
+
stream
|
|
332
|
+
}
|
|
333
|
+
})
|
|
334
|
+
t.after(() => fastify.close())
|
|
335
|
+
|
|
336
|
+
fastify.get('/', function (req, reply) {
|
|
337
|
+
t.assert.ok(req.log)
|
|
338
|
+
reply.send({ hello: 'world' })
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
await fastify.ready()
|
|
342
|
+
await fastify.listen({ port: 0 })
|
|
343
|
+
|
|
344
|
+
await request(`http://${localhostForURL}:` + fastify.server.address().port)
|
|
345
|
+
|
|
346
|
+
let id
|
|
347
|
+
for await (const [line] of on(stream, 'data')) {
|
|
348
|
+
// we skip the non-request log
|
|
349
|
+
if (typeof line.reqId !== 'string') continue
|
|
350
|
+
if (id === undefined && line.reqId) id = line.reqId
|
|
351
|
+
if (id !== undefined && line.reqId) t.assert.strictEqual(line.reqId, id)
|
|
352
|
+
t.assert.ok(partialDeepStrictEqual(line, lines.shift()))
|
|
353
|
+
if (lines.length === 0) break
|
|
354
|
+
}
|
|
355
|
+
})
|
|
356
|
+
|
|
357
|
+
await t.test('test log stream', async (t) => {
|
|
358
|
+
const stream = split(JSON.parse)
|
|
359
|
+
const fastify = Fastify({
|
|
360
|
+
logger: {
|
|
361
|
+
stream,
|
|
362
|
+
level: 'info'
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
t.after(() => fastify.close())
|
|
366
|
+
|
|
367
|
+
fastify.get('/', function (req, reply) {
|
|
368
|
+
t.assert.ok(req.log)
|
|
369
|
+
reply.send({ hello: 'world' })
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
await fastify.ready()
|
|
373
|
+
const server = await fastify.listen({ port: 0, host: localhost })
|
|
374
|
+
const lines = [
|
|
375
|
+
{ msg: `Server listening at ${server}` },
|
|
376
|
+
{ req: { method: 'GET' }, msg: 'incoming request' },
|
|
377
|
+
{ res: { statusCode: 200 }, msg: 'request completed' }
|
|
378
|
+
]
|
|
379
|
+
t.plan(lines.length + 3)
|
|
380
|
+
|
|
381
|
+
await request(`http://${localhostForURL}:` + fastify.server.address().port)
|
|
382
|
+
|
|
383
|
+
let id
|
|
384
|
+
for await (const [line] of on(stream, 'data')) {
|
|
385
|
+
if (id === undefined && line.reqId) id = line.reqId
|
|
386
|
+
if (id !== undefined && line.reqId) t.assert.strictEqual(line.reqId, id)
|
|
387
|
+
t.assert.ok(partialDeepStrictEqual(line, lines.shift()))
|
|
388
|
+
if (lines.length === 0) break
|
|
389
|
+
}
|
|
390
|
+
})
|
|
391
|
+
|
|
392
|
+
await t.test('test error log stream', async (t) => {
|
|
393
|
+
const stream = split(JSON.parse)
|
|
394
|
+
const fastify = Fastify({
|
|
395
|
+
logger: {
|
|
396
|
+
stream,
|
|
397
|
+
level: 'info'
|
|
398
|
+
}
|
|
399
|
+
})
|
|
400
|
+
t.after(() => fastify.close())
|
|
401
|
+
|
|
402
|
+
fastify.get('/error', function (req, reply) {
|
|
403
|
+
t.assert.ok(req.log)
|
|
404
|
+
reply.send(new Error('kaboom'))
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
await fastify.ready()
|
|
408
|
+
const server = await fastify.listen({ port: 0, host: localhost })
|
|
409
|
+
const lines = [
|
|
410
|
+
{ msg: `Server listening at ${server}` },
|
|
411
|
+
{ req: { method: 'GET' }, msg: 'incoming request' },
|
|
412
|
+
{ res: { statusCode: 500 }, msg: 'kaboom' },
|
|
413
|
+
{ res: { statusCode: 500 }, msg: 'request completed' }
|
|
414
|
+
]
|
|
415
|
+
t.plan(lines.length + 4)
|
|
416
|
+
|
|
417
|
+
await request(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
418
|
+
|
|
419
|
+
let id
|
|
420
|
+
for await (const [line] of on(stream, 'data')) {
|
|
421
|
+
if (id === undefined && line.reqId) id = line.reqId
|
|
422
|
+
if (id !== undefined && line.reqId) t.assert.strictEqual(line.reqId, id)
|
|
423
|
+
t.assert.ok(partialDeepStrictEqual(line, lines.shift()))
|
|
424
|
+
if (lines.length === 0) break
|
|
425
|
+
}
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
await t.test('should not log the error if request logging is disabled', async (t) => {
|
|
429
|
+
t.plan(4)
|
|
430
|
+
|
|
431
|
+
const stream = split(JSON.parse)
|
|
432
|
+
const fastify = Fastify({
|
|
433
|
+
logger: {
|
|
434
|
+
stream,
|
|
435
|
+
level: 'info'
|
|
436
|
+
},
|
|
437
|
+
disableRequestLogging: true
|
|
438
|
+
})
|
|
439
|
+
t.after(() => fastify.close())
|
|
440
|
+
|
|
441
|
+
fastify.get('/error', function (req, reply) {
|
|
442
|
+
t.assert.ok(req.log)
|
|
443
|
+
reply.send(new Error('a generic error'))
|
|
444
|
+
})
|
|
445
|
+
|
|
446
|
+
await fastify.ready()
|
|
447
|
+
await fastify.listen({ port: 0, host: localhost })
|
|
448
|
+
|
|
449
|
+
await request(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
450
|
+
|
|
451
|
+
{
|
|
452
|
+
const [line] = await once(stream, 'data')
|
|
453
|
+
t.assert.ok(typeof line.msg === 'string')
|
|
454
|
+
t.assert.ok(line.msg.startsWith('Server listening at'), 'message is set')
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// no more readable data
|
|
458
|
+
t.assert.strictEqual(stream.readableLength, 0)
|
|
459
|
+
})
|
|
460
|
+
})
|