fastify 5.3.2 → 5.3.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/.vscode/settings.json +22 -0
- package/docs/Guides/Ecosystem.md +7 -2
- package/docs/Guides/Serverless.md +28 -69
- package/docs/Reference/Errors.md +0 -2
- package/docs/Reference/Server.md +17 -1
- package/eslint.config.js +17 -9
- package/fastify.js +6 -2
- package/lib/decorate.js +2 -2
- package/lib/errors.js +0 -8
- package/lib/logger-factory.js +1 -1
- package/lib/logger-pino.js +2 -2
- package/lib/reply.js +2 -2
- package/lib/request.js +1 -1
- package/lib/server.js +30 -51
- package/package.json +4 -4
- package/test/close-pipelining.test.js +5 -4
- package/test/decorator.test.js +422 -341
- package/test/helper.js +107 -69
- package/test/hooks.on-listen.test.js +255 -239
- package/test/hooks.on-ready.test.js +110 -92
- package/test/inject.test.js +114 -97
- package/test/input-validation.js +63 -53
- package/test/internals/errors.test.js +1 -11
- package/test/internals/hooks.test.js +17 -0
- package/test/issue-4959.test.js +2 -2
- package/test/logger/response.test.js +19 -20
- package/test/options.error-handler.test.js +1 -1
- package/test/options.test.js +1 -1
- package/test/output-validation.test.js +49 -70
- package/test/patch.error-handler.test.js +1 -1
- package/test/patch.test.js +1 -1
- package/test/plugin.1.test.js +71 -60
- package/test/promises.test.js +36 -30
- package/test/put.error-handler.test.js +1 -1
- package/test/put.test.js +1 -1
- package/test/reply-error.test.js +169 -148
- package/test/reply-trailers.test.js +119 -108
- package/test/schema-feature.test.js +309 -238
- package/test/schema-validation.test.js +44 -2
- package/test/stream.1.test.js +30 -27
- package/test/stream.2.test.js +20 -10
- package/test/stream.3.test.js +37 -31
- package/test/types/errors.test-d.ts +0 -1
- package/test/types/plugin.test-d.ts +1 -1
- package/test/types/register.test-d.ts +1 -1
- package/test/use-semicolon-delimiter.test.js +1 -1
- package/types/errors.d.ts +0 -1
- package/test/http2/missing-http2-module.test.js +0 -17
package/test/reply-error.test.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const test = t.test
|
|
3
|
+
const { test, describe } = require('node:test')
|
|
5
4
|
const net = require('node:net')
|
|
6
5
|
const Fastify = require('..')
|
|
7
6
|
const statusCodes = require('node:http').STATUS_CODES
|
|
@@ -15,10 +14,10 @@ codes.forEach(code => {
|
|
|
15
14
|
})
|
|
16
15
|
|
|
17
16
|
function helper (code) {
|
|
18
|
-
test('Reply error handling - code: ' + code, t => {
|
|
17
|
+
test('Reply error handling - code: ' + code, (t, testDone) => {
|
|
19
18
|
t.plan(4)
|
|
20
19
|
const fastify = Fastify()
|
|
21
|
-
t.
|
|
20
|
+
t.after(() => fastify.close())
|
|
22
21
|
const err = new Error('winter is coming')
|
|
23
22
|
|
|
24
23
|
fastify.get('/', (req, reply) => {
|
|
@@ -31,10 +30,10 @@ function helper (code) {
|
|
|
31
30
|
method: 'GET',
|
|
32
31
|
url: '/'
|
|
33
32
|
}, (error, res) => {
|
|
34
|
-
t.
|
|
35
|
-
t.
|
|
36
|
-
t.
|
|
37
|
-
t.
|
|
33
|
+
t.assert.ifError(error)
|
|
34
|
+
t.assert.strictEqual(res.statusCode, Number(code))
|
|
35
|
+
t.assert.strictEqual(res.headers['content-type'], 'application/json; charset=utf-8')
|
|
36
|
+
t.assert.deepStrictEqual(
|
|
38
37
|
{
|
|
39
38
|
error: statusCodes[code],
|
|
40
39
|
message: err.message,
|
|
@@ -42,14 +41,15 @@ function helper (code) {
|
|
|
42
41
|
},
|
|
43
42
|
JSON.parse(res.payload)
|
|
44
43
|
)
|
|
44
|
+
testDone()
|
|
45
45
|
})
|
|
46
46
|
})
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
test('preHandler hook error handling with external code', t => {
|
|
49
|
+
test('preHandler hook error handling with external code', (t, testDone) => {
|
|
50
50
|
t.plan(3)
|
|
51
51
|
const fastify = Fastify()
|
|
52
|
-
t.
|
|
52
|
+
t.after(() => fastify.close())
|
|
53
53
|
const err = new Error('winter is coming')
|
|
54
54
|
|
|
55
55
|
fastify.addHook('preHandler', (req, reply, done) => {
|
|
@@ -63,9 +63,9 @@ test('preHandler hook error handling with external code', t => {
|
|
|
63
63
|
method: 'GET',
|
|
64
64
|
url: '/'
|
|
65
65
|
}, (error, res) => {
|
|
66
|
-
t.
|
|
67
|
-
t.
|
|
68
|
-
t.
|
|
66
|
+
t.assert.ifError(error)
|
|
67
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
68
|
+
t.assert.deepStrictEqual(
|
|
69
69
|
{
|
|
70
70
|
error: statusCodes['400'],
|
|
71
71
|
message: err.message,
|
|
@@ -73,13 +73,14 @@ test('preHandler hook error handling with external code', t => {
|
|
|
73
73
|
},
|
|
74
74
|
JSON.parse(res.payload)
|
|
75
75
|
)
|
|
76
|
+
testDone()
|
|
76
77
|
})
|
|
77
78
|
})
|
|
78
79
|
|
|
79
|
-
test('onRequest hook error handling with external done', t => {
|
|
80
|
+
test('onRequest hook error handling with external done', (t, testDone) => {
|
|
80
81
|
t.plan(3)
|
|
81
82
|
const fastify = Fastify()
|
|
82
|
-
t.
|
|
83
|
+
t.after(() => fastify.close())
|
|
83
84
|
const err = new Error('winter is coming')
|
|
84
85
|
|
|
85
86
|
fastify.addHook('onRequest', (req, reply, done) => {
|
|
@@ -93,9 +94,9 @@ test('onRequest hook error handling with external done', t => {
|
|
|
93
94
|
method: 'GET',
|
|
94
95
|
url: '/'
|
|
95
96
|
}, (error, res) => {
|
|
96
|
-
t.
|
|
97
|
-
t.
|
|
98
|
-
t.
|
|
97
|
+
t.assert.ifError(error)
|
|
98
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
99
|
+
t.assert.deepStrictEqual(
|
|
99
100
|
{
|
|
100
101
|
error: statusCodes['400'],
|
|
101
102
|
message: err.message,
|
|
@@ -103,16 +104,17 @@ test('onRequest hook error handling with external done', t => {
|
|
|
103
104
|
},
|
|
104
105
|
JSON.parse(res.payload)
|
|
105
106
|
)
|
|
107
|
+
testDone()
|
|
106
108
|
})
|
|
107
109
|
})
|
|
108
110
|
|
|
109
|
-
test('Should reply 400 on client error', t => {
|
|
111
|
+
test('Should reply 400 on client error', (t, testDone) => {
|
|
110
112
|
t.plan(2)
|
|
111
113
|
|
|
112
114
|
const fastify = Fastify()
|
|
113
|
-
t.
|
|
115
|
+
t.after(() => fastify.close())
|
|
114
116
|
fastify.listen({ port: 0, host: '127.0.0.1' }, err => {
|
|
115
|
-
t.
|
|
117
|
+
t.assert.ifError(err)
|
|
116
118
|
|
|
117
119
|
const client = net.connect(fastify.server.address().port, '127.0.0.1')
|
|
118
120
|
client.end('oooops!')
|
|
@@ -128,12 +130,13 @@ test('Should reply 400 on client error', t => {
|
|
|
128
130
|
message: 'Client Error',
|
|
129
131
|
statusCode: 400
|
|
130
132
|
})
|
|
131
|
-
t.
|
|
133
|
+
t.assert.strictEqual(`HTTP/1.1 400 Bad Request\r\nContent-Length: ${body.length}\r\nContent-Type: application/json\r\n\r\n${body}`, chunks)
|
|
134
|
+
testDone()
|
|
132
135
|
})
|
|
133
136
|
})
|
|
134
137
|
})
|
|
135
138
|
|
|
136
|
-
test('Should set the response from client error handler', t => {
|
|
139
|
+
test('Should set the response from client error handler', (t, testDone) => {
|
|
137
140
|
t.plan(5)
|
|
138
141
|
|
|
139
142
|
const responseBody = JSON.stringify({
|
|
@@ -144,7 +147,7 @@ test('Should set the response from client error handler', t => {
|
|
|
144
147
|
const response = `HTTP/1.1 400 Bad Request\r\nContent-Length: ${responseBody.length}\r\nContent-Type: application/json; charset=utf-8\r\n\r\n${responseBody}`
|
|
145
148
|
|
|
146
149
|
function clientErrorHandler (err, socket) {
|
|
147
|
-
t.
|
|
150
|
+
t.assert.ok(err instanceof Error)
|
|
148
151
|
|
|
149
152
|
this.log.warn({ err }, 'Handled client error')
|
|
150
153
|
socket.end(response)
|
|
@@ -160,8 +163,8 @@ test('Should set the response from client error handler', t => {
|
|
|
160
163
|
})
|
|
161
164
|
|
|
162
165
|
fastify.listen({ port: 0, host: '127.0.0.1' }, err => {
|
|
163
|
-
t.
|
|
164
|
-
t.
|
|
166
|
+
t.assert.ifError(err)
|
|
167
|
+
t.after(() => fastify.close())
|
|
165
168
|
|
|
166
169
|
const client = net.connect(fastify.server.address().port, '127.0.0.1')
|
|
167
170
|
client.end('oooops!')
|
|
@@ -172,20 +175,22 @@ test('Should set the response from client error handler', t => {
|
|
|
172
175
|
})
|
|
173
176
|
|
|
174
177
|
client.once('end', () => {
|
|
175
|
-
t.
|
|
178
|
+
t.assert.strictEqual(response, chunks)
|
|
179
|
+
|
|
180
|
+
testDone()
|
|
176
181
|
})
|
|
177
182
|
})
|
|
178
183
|
|
|
179
184
|
logStream.once('data', line => {
|
|
180
|
-
t.
|
|
181
|
-
t.
|
|
185
|
+
t.assert.strictEqual('Handled client error', line.msg)
|
|
186
|
+
t.assert.strictEqual(40, line.level, 'Log level is not warn')
|
|
182
187
|
})
|
|
183
188
|
})
|
|
184
189
|
|
|
185
|
-
test('Error instance sets HTTP status code', t => {
|
|
190
|
+
test('Error instance sets HTTP status code', (t, testDone) => {
|
|
186
191
|
t.plan(3)
|
|
187
192
|
const fastify = Fastify()
|
|
188
|
-
t.
|
|
193
|
+
t.after(() => fastify.close())
|
|
189
194
|
const err = new Error('winter is coming')
|
|
190
195
|
err.statusCode = 418
|
|
191
196
|
|
|
@@ -197,9 +202,9 @@ test('Error instance sets HTTP status code', t => {
|
|
|
197
202
|
method: 'GET',
|
|
198
203
|
url: '/'
|
|
199
204
|
}, (error, res) => {
|
|
200
|
-
t.
|
|
201
|
-
t.
|
|
202
|
-
t.
|
|
205
|
+
t.assert.ifError(error)
|
|
206
|
+
t.assert.strictEqual(res.statusCode, 418)
|
|
207
|
+
t.assert.deepStrictEqual(
|
|
203
208
|
{
|
|
204
209
|
error: statusCodes['418'],
|
|
205
210
|
message: err.message,
|
|
@@ -207,13 +212,14 @@ test('Error instance sets HTTP status code', t => {
|
|
|
207
212
|
},
|
|
208
213
|
JSON.parse(res.payload)
|
|
209
214
|
)
|
|
215
|
+
testDone()
|
|
210
216
|
})
|
|
211
217
|
})
|
|
212
218
|
|
|
213
|
-
test('Error status code below 400 defaults to 500', t => {
|
|
219
|
+
test('Error status code below 400 defaults to 500', (t, testDone) => {
|
|
214
220
|
t.plan(3)
|
|
215
221
|
const fastify = Fastify()
|
|
216
|
-
t.
|
|
222
|
+
t.after(() => fastify.close())
|
|
217
223
|
const err = new Error('winter is coming')
|
|
218
224
|
err.statusCode = 399
|
|
219
225
|
|
|
@@ -225,9 +231,9 @@ test('Error status code below 400 defaults to 500', t => {
|
|
|
225
231
|
method: 'GET',
|
|
226
232
|
url: '/'
|
|
227
233
|
}, (error, res) => {
|
|
228
|
-
t.
|
|
229
|
-
t.
|
|
230
|
-
t.
|
|
234
|
+
t.assert.ifError(error)
|
|
235
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
236
|
+
t.assert.deepStrictEqual(
|
|
231
237
|
{
|
|
232
238
|
error: statusCodes['500'],
|
|
233
239
|
message: err.message,
|
|
@@ -235,13 +241,14 @@ test('Error status code below 400 defaults to 500', t => {
|
|
|
235
241
|
},
|
|
236
242
|
JSON.parse(res.payload)
|
|
237
243
|
)
|
|
244
|
+
testDone()
|
|
238
245
|
})
|
|
239
246
|
})
|
|
240
247
|
|
|
241
|
-
test('Error.status property support', t => {
|
|
248
|
+
test('Error.status property support', (t, testDone) => {
|
|
242
249
|
t.plan(3)
|
|
243
250
|
const fastify = Fastify()
|
|
244
|
-
t.
|
|
251
|
+
t.after(() => fastify.close())
|
|
245
252
|
const err = new Error('winter is coming')
|
|
246
253
|
err.status = 418
|
|
247
254
|
|
|
@@ -253,9 +260,9 @@ test('Error.status property support', t => {
|
|
|
253
260
|
method: 'GET',
|
|
254
261
|
url: '/'
|
|
255
262
|
}, (error, res) => {
|
|
256
|
-
t.
|
|
257
|
-
t.
|
|
258
|
-
t.
|
|
263
|
+
t.assert.ifError(error)
|
|
264
|
+
t.assert.strictEqual(res.statusCode, 418)
|
|
265
|
+
t.assert.deepStrictEqual(
|
|
259
266
|
{
|
|
260
267
|
error: statusCodes['418'],
|
|
261
268
|
message: err.message,
|
|
@@ -263,10 +270,11 @@ test('Error.status property support', t => {
|
|
|
263
270
|
},
|
|
264
271
|
JSON.parse(res.payload)
|
|
265
272
|
)
|
|
273
|
+
testDone()
|
|
266
274
|
})
|
|
267
275
|
})
|
|
268
276
|
|
|
269
|
-
|
|
277
|
+
describe('Support rejection with values that are not Error instances', () => {
|
|
270
278
|
const objs = [
|
|
271
279
|
0,
|
|
272
280
|
'',
|
|
@@ -280,12 +288,11 @@ test('Support rejection with values that are not Error instances', t => {
|
|
|
280
288
|
new Date(),
|
|
281
289
|
new Uint8Array()
|
|
282
290
|
]
|
|
283
|
-
t.plan(objs.length)
|
|
284
291
|
for (const nonErr of objs) {
|
|
285
|
-
|
|
292
|
+
test('Type: ' + typeof nonErr, (t, testDone) => {
|
|
286
293
|
t.plan(4)
|
|
287
294
|
const fastify = Fastify()
|
|
288
|
-
t.
|
|
295
|
+
t.after(() => fastify.close())
|
|
289
296
|
|
|
290
297
|
fastify.get('/', () => {
|
|
291
298
|
return Promise.reject(nonErr)
|
|
@@ -293,9 +300,9 @@ test('Support rejection with values that are not Error instances', t => {
|
|
|
293
300
|
|
|
294
301
|
fastify.setErrorHandler((err, request, reply) => {
|
|
295
302
|
if (typeof err === 'object') {
|
|
296
|
-
t.
|
|
303
|
+
t.assert.deepStrictEqual(err, nonErr)
|
|
297
304
|
} else {
|
|
298
|
-
t.
|
|
305
|
+
t.assert.strictEqual(err, nonErr)
|
|
299
306
|
}
|
|
300
307
|
reply.code(500).send('error')
|
|
301
308
|
})
|
|
@@ -304,19 +311,20 @@ test('Support rejection with values that are not Error instances', t => {
|
|
|
304
311
|
method: 'GET',
|
|
305
312
|
url: '/'
|
|
306
313
|
}, (error, res) => {
|
|
307
|
-
t.
|
|
308
|
-
t.
|
|
309
|
-
t.
|
|
314
|
+
t.assert.ifError(error)
|
|
315
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
316
|
+
t.assert.strictEqual(res.payload, 'error')
|
|
317
|
+
testDone()
|
|
310
318
|
})
|
|
311
319
|
})
|
|
312
320
|
}
|
|
313
321
|
})
|
|
314
322
|
|
|
315
|
-
test('invalid schema - ajv', t => {
|
|
323
|
+
test('invalid schema - ajv', (t, testDone) => {
|
|
316
324
|
t.plan(4)
|
|
317
325
|
|
|
318
326
|
const fastify = Fastify()
|
|
319
|
-
t.
|
|
327
|
+
t.after(() => fastify.close())
|
|
320
328
|
fastify.get('/', {
|
|
321
329
|
schema: {
|
|
322
330
|
querystring: {
|
|
@@ -327,11 +335,11 @@ test('invalid schema - ajv', t => {
|
|
|
327
335
|
}
|
|
328
336
|
}
|
|
329
337
|
}, (req, reply) => {
|
|
330
|
-
t.fail('we should not be here')
|
|
338
|
+
t.assert.fail('we should not be here')
|
|
331
339
|
})
|
|
332
340
|
|
|
333
341
|
fastify.setErrorHandler((err, request, reply) => {
|
|
334
|
-
t.ok(Array.isArray(err.validation))
|
|
342
|
+
t.assert.ok(Array.isArray(err.validation))
|
|
335
343
|
reply.code(400).send('error')
|
|
336
344
|
})
|
|
337
345
|
|
|
@@ -339,16 +347,17 @@ test('invalid schema - ajv', t => {
|
|
|
339
347
|
url: '/?id=abc',
|
|
340
348
|
method: 'GET'
|
|
341
349
|
}, (err, res) => {
|
|
342
|
-
t.
|
|
343
|
-
t.
|
|
344
|
-
t.
|
|
350
|
+
t.assert.ifError(err)
|
|
351
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
352
|
+
t.assert.strictEqual(res.payload, 'error')
|
|
353
|
+
testDone()
|
|
345
354
|
})
|
|
346
355
|
})
|
|
347
356
|
|
|
348
|
-
test('should set the status code and the headers from the error object (from route handler) (no custom error handler)', t => {
|
|
357
|
+
test('should set the status code and the headers from the error object (from route handler) (no custom error handler)', (t, testDone) => {
|
|
349
358
|
t.plan(4)
|
|
350
359
|
const fastify = Fastify()
|
|
351
|
-
t.
|
|
360
|
+
t.after(() => fastify.close())
|
|
352
361
|
|
|
353
362
|
fastify.get('/', (req, reply) => {
|
|
354
363
|
const error = new Error('kaboom')
|
|
@@ -361,21 +370,23 @@ test('should set the status code and the headers from the error object (from rou
|
|
|
361
370
|
url: '/',
|
|
362
371
|
method: 'GET'
|
|
363
372
|
}, (err, res) => {
|
|
364
|
-
t.
|
|
365
|
-
t.
|
|
366
|
-
t.
|
|
367
|
-
t.
|
|
373
|
+
t.assert.ifError(err)
|
|
374
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
375
|
+
t.assert.strictEqual(res.headers.hello, 'world')
|
|
376
|
+
t.assert.deepStrictEqual(JSON.parse(res.payload), {
|
|
368
377
|
error: 'Bad Request',
|
|
369
378
|
message: 'kaboom',
|
|
370
379
|
statusCode: 400
|
|
371
380
|
})
|
|
381
|
+
|
|
382
|
+
testDone()
|
|
372
383
|
})
|
|
373
384
|
})
|
|
374
385
|
|
|
375
|
-
test('should set the status code and the headers from the error object (from custom error handler)', t => {
|
|
386
|
+
test('should set the status code and the headers from the error object (from custom error handler)', (t, testDone) => {
|
|
376
387
|
t.plan(6)
|
|
377
388
|
const fastify = Fastify()
|
|
378
|
-
t.
|
|
389
|
+
t.after(() => fastify.close())
|
|
379
390
|
|
|
380
391
|
fastify.get('/', (req, reply) => {
|
|
381
392
|
const error = new Error('ouch')
|
|
@@ -384,8 +395,8 @@ test('should set the status code and the headers from the error object (from cus
|
|
|
384
395
|
})
|
|
385
396
|
|
|
386
397
|
fastify.setErrorHandler((err, request, reply) => {
|
|
387
|
-
t.
|
|
388
|
-
t.
|
|
398
|
+
t.assert.strictEqual(err.message, 'ouch')
|
|
399
|
+
t.assert.strictEqual(reply.raw.statusCode, 200)
|
|
389
400
|
const error = new Error('kaboom')
|
|
390
401
|
error.headers = { hello: 'world' }
|
|
391
402
|
error.statusCode = 400
|
|
@@ -396,31 +407,33 @@ test('should set the status code and the headers from the error object (from cus
|
|
|
396
407
|
url: '/',
|
|
397
408
|
method: 'GET'
|
|
398
409
|
}, (err, res) => {
|
|
399
|
-
t.
|
|
400
|
-
t.
|
|
401
|
-
t.
|
|
402
|
-
t.
|
|
410
|
+
t.assert.ifError(err)
|
|
411
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
412
|
+
t.assert.strictEqual(res.headers.hello, 'world')
|
|
413
|
+
t.assert.deepStrictEqual(JSON.parse(res.payload), {
|
|
403
414
|
error: 'Bad Request',
|
|
404
415
|
message: 'kaboom',
|
|
405
416
|
statusCode: 400
|
|
406
417
|
})
|
|
418
|
+
testDone()
|
|
407
419
|
})
|
|
408
420
|
})
|
|
409
421
|
|
|
410
422
|
// Issue 595 https://github.com/fastify/fastify/issues/595
|
|
411
|
-
test('\'*\' should throw an error due to serializer can not handle the payload type', t => {
|
|
423
|
+
test('\'*\' should throw an error due to serializer can not handle the payload type', (t, testDone) => {
|
|
412
424
|
t.plan(3)
|
|
413
425
|
const fastify = Fastify()
|
|
414
|
-
t.
|
|
426
|
+
t.after(() => fastify.close())
|
|
415
427
|
|
|
416
428
|
fastify.get('/', (req, reply) => {
|
|
417
429
|
reply.type('text/html')
|
|
418
430
|
try {
|
|
419
431
|
reply.send({})
|
|
420
432
|
} catch (err) {
|
|
421
|
-
t.
|
|
422
|
-
t.
|
|
423
|
-
t.
|
|
433
|
+
t.assert.ok(err instanceof TypeError)
|
|
434
|
+
t.assert.strictEqual(err.code, 'FST_ERR_REP_INVALID_PAYLOAD_TYPE')
|
|
435
|
+
t.assert.strictEqual(err.message, "Attempted to send payload of invalid type 'object'. Expected a string or Buffer.")
|
|
436
|
+
testDone()
|
|
424
437
|
}
|
|
425
438
|
})
|
|
426
439
|
|
|
@@ -428,14 +441,14 @@ test('\'*\' should throw an error due to serializer can not handle the payload t
|
|
|
428
441
|
url: '/',
|
|
429
442
|
method: 'GET'
|
|
430
443
|
}, (e, res) => {
|
|
431
|
-
t.fail('should not be called')
|
|
444
|
+
t.assert.fail('should not be called')
|
|
432
445
|
})
|
|
433
446
|
})
|
|
434
447
|
|
|
435
|
-
test('should throw an error if the custom serializer does not serialize the payload to a valid type', t => {
|
|
448
|
+
test('should throw an error if the custom serializer does not serialize the payload to a valid type', (t, testDone) => {
|
|
436
449
|
t.plan(3)
|
|
437
450
|
const fastify = Fastify()
|
|
438
|
-
t.
|
|
451
|
+
t.after(() => fastify.close())
|
|
439
452
|
|
|
440
453
|
fastify.get('/', (req, reply) => {
|
|
441
454
|
try {
|
|
@@ -444,9 +457,10 @@ test('should throw an error if the custom serializer does not serialize the payl
|
|
|
444
457
|
.serializer(payload => payload)
|
|
445
458
|
.send({})
|
|
446
459
|
} catch (err) {
|
|
447
|
-
t.
|
|
448
|
-
t.
|
|
449
|
-
t.
|
|
460
|
+
t.assert.ok(err instanceof TypeError)
|
|
461
|
+
t.assert.strictEqual(err.code, 'FST_ERR_REP_INVALID_PAYLOAD_TYPE')
|
|
462
|
+
t.assert.strictEqual(err.message, "Attempted to send payload of invalid type 'object'. Expected a string or Buffer.")
|
|
463
|
+
testDone()
|
|
450
464
|
}
|
|
451
465
|
})
|
|
452
466
|
|
|
@@ -454,15 +468,15 @@ test('should throw an error if the custom serializer does not serialize the payl
|
|
|
454
468
|
url: '/',
|
|
455
469
|
method: 'GET'
|
|
456
470
|
}, (e, res) => {
|
|
457
|
-
t.fail('should not be called')
|
|
471
|
+
t.assert.fail('should not be called')
|
|
458
472
|
})
|
|
459
473
|
})
|
|
460
474
|
|
|
461
|
-
test('should not set headers or status code for custom error handler', t => {
|
|
475
|
+
test('should not set headers or status code for custom error handler', (t, testDone) => {
|
|
462
476
|
t.plan(7)
|
|
463
477
|
|
|
464
478
|
const fastify = Fastify()
|
|
465
|
-
t.
|
|
479
|
+
t.after(() => fastify.close())
|
|
466
480
|
fastify.get('/', function (req, reply) {
|
|
467
481
|
const err = new Error('kaboom')
|
|
468
482
|
err.headers = {
|
|
@@ -472,8 +486,8 @@ test('should not set headers or status code for custom error handler', t => {
|
|
|
472
486
|
})
|
|
473
487
|
|
|
474
488
|
fastify.setErrorHandler(async (err, req, res) => {
|
|
475
|
-
t.
|
|
476
|
-
t.
|
|
489
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
490
|
+
t.assert.strictEqual('fake-random-header' in res.headers, false)
|
|
477
491
|
return res.code(500).send(err.message)
|
|
478
492
|
})
|
|
479
493
|
|
|
@@ -481,19 +495,20 @@ test('should not set headers or status code for custom error handler', t => {
|
|
|
481
495
|
method: 'GET',
|
|
482
496
|
url: '/'
|
|
483
497
|
}, (err, res) => {
|
|
484
|
-
t.
|
|
485
|
-
t.
|
|
486
|
-
t.
|
|
487
|
-
t.
|
|
488
|
-
t.
|
|
498
|
+
t.assert.ifError(err)
|
|
499
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
500
|
+
t.assert.strictEqual('fake-random-header' in res.headers, false)
|
|
501
|
+
t.assert.strictEqual(res.headers['content-length'], ('kaboom'.length).toString())
|
|
502
|
+
t.assert.deepStrictEqual(res.payload, 'kaboom')
|
|
503
|
+
testDone()
|
|
489
504
|
})
|
|
490
505
|
})
|
|
491
506
|
|
|
492
|
-
test('error thrown by custom error handler routes to default error handler', t => {
|
|
507
|
+
test('error thrown by custom error handler routes to default error handler', (t, testDone) => {
|
|
493
508
|
t.plan(6)
|
|
494
509
|
|
|
495
510
|
const fastify = Fastify()
|
|
496
|
-
t.
|
|
511
|
+
t.after(() => fastify.close())
|
|
497
512
|
|
|
498
513
|
const error = new Error('kaboom')
|
|
499
514
|
error.headers = {
|
|
@@ -507,9 +522,9 @@ test('error thrown by custom error handler routes to default error handler', t =
|
|
|
507
522
|
const newError = new Error('kabong')
|
|
508
523
|
|
|
509
524
|
fastify.setErrorHandler(async (err, req, res) => {
|
|
510
|
-
t.
|
|
511
|
-
t.
|
|
512
|
-
t.
|
|
525
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
526
|
+
t.assert.strictEqual('fake-random-header' in res.headers, false)
|
|
527
|
+
t.assert.deepStrictEqual(err.headers, error.headers)
|
|
513
528
|
|
|
514
529
|
return res.send(newError)
|
|
515
530
|
})
|
|
@@ -518,24 +533,25 @@ test('error thrown by custom error handler routes to default error handler', t =
|
|
|
518
533
|
method: 'GET',
|
|
519
534
|
url: '/'
|
|
520
535
|
}, (err, res) => {
|
|
521
|
-
t.
|
|
522
|
-
t.
|
|
523
|
-
t.
|
|
536
|
+
t.assert.ifError(err)
|
|
537
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
538
|
+
t.assert.deepStrictEqual(JSON.parse(res.payload), {
|
|
524
539
|
error: statusCodes['500'],
|
|
525
540
|
message: newError.message,
|
|
526
541
|
statusCode: 500
|
|
527
542
|
})
|
|
543
|
+
testDone()
|
|
528
544
|
})
|
|
529
545
|
})
|
|
530
546
|
|
|
531
547
|
// Refs: https://github.com/fastify/fastify/pull/4484#issuecomment-1367301750
|
|
532
|
-
test('allow re-thrown error to default error handler when route handler is async and error handler is sync', t => {
|
|
548
|
+
test('allow re-thrown error to default error handler when route handler is async and error handler is sync', (t, testDone) => {
|
|
533
549
|
t.plan(4)
|
|
534
550
|
const fastify = Fastify()
|
|
535
|
-
t.
|
|
551
|
+
t.after(() => fastify.close())
|
|
536
552
|
|
|
537
553
|
fastify.setErrorHandler(function (error) {
|
|
538
|
-
t.
|
|
554
|
+
t.assert.strictEqual(error.message, 'kaboom')
|
|
539
555
|
throw Error('kabong')
|
|
540
556
|
})
|
|
541
557
|
|
|
@@ -547,13 +563,14 @@ test('allow re-thrown error to default error handler when route handler is async
|
|
|
547
563
|
url: '/',
|
|
548
564
|
method: 'GET'
|
|
549
565
|
}, (err, res) => {
|
|
550
|
-
t.
|
|
551
|
-
t.
|
|
552
|
-
t.
|
|
566
|
+
t.assert.ifError(err)
|
|
567
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
568
|
+
t.assert.deepStrictEqual(JSON.parse(res.payload), {
|
|
553
569
|
error: statusCodes['500'],
|
|
554
570
|
message: 'kabong',
|
|
555
571
|
statusCode: 500
|
|
556
572
|
})
|
|
573
|
+
testDone()
|
|
557
574
|
})
|
|
558
575
|
})
|
|
559
576
|
|
|
@@ -572,32 +589,34 @@ const invalidErrorCodes = [
|
|
|
572
589
|
700
|
|
573
590
|
]
|
|
574
591
|
invalidErrorCodes.forEach((invalidCode) => {
|
|
575
|
-
test(`should throw error if error code is ${invalidCode}`, t => {
|
|
592
|
+
test(`should throw error if error code is ${invalidCode}`, (t, testDone) => {
|
|
576
593
|
t.plan(2)
|
|
577
594
|
const fastify = Fastify()
|
|
578
|
-
t.
|
|
595
|
+
t.after(() => fastify.close())
|
|
579
596
|
fastify.get('/', (request, reply) => {
|
|
580
597
|
try {
|
|
581
598
|
return reply.code(invalidCode).send('You should not read this')
|
|
582
599
|
} catch (err) {
|
|
583
|
-
t.
|
|
584
|
-
t.
|
|
600
|
+
t.assert.strictEqual(err.code, 'FST_ERR_BAD_STATUS_CODE')
|
|
601
|
+
t.assert.strictEqual(err.message, 'Called reply with an invalid status code: ' + invalidCode)
|
|
602
|
+
testDone()
|
|
585
603
|
}
|
|
586
604
|
})
|
|
605
|
+
|
|
587
606
|
fastify.inject({
|
|
588
607
|
url: '/',
|
|
589
608
|
method: 'GET'
|
|
590
609
|
}, (e, res) => {
|
|
591
|
-
t.fail('should not be called')
|
|
610
|
+
t.assert.fail('should not be called')
|
|
592
611
|
})
|
|
593
612
|
})
|
|
594
613
|
})
|
|
595
614
|
|
|
596
|
-
test('error handler is triggered when a string is thrown from sync handler', t => {
|
|
615
|
+
test('error handler is triggered when a string is thrown from sync handler', (t, testDone) => {
|
|
597
616
|
t.plan(3)
|
|
598
617
|
|
|
599
618
|
const fastify = Fastify()
|
|
600
|
-
t.
|
|
619
|
+
t.after(() => fastify.close())
|
|
601
620
|
|
|
602
621
|
const throwable = 'test'
|
|
603
622
|
const payload = 'error'
|
|
@@ -607,7 +626,7 @@ test('error handler is triggered when a string is thrown from sync handler', t =
|
|
|
607
626
|
})
|
|
608
627
|
|
|
609
628
|
fastify.setErrorHandler((err, req, res) => {
|
|
610
|
-
t.
|
|
629
|
+
t.assert.strictEqual(err, throwable)
|
|
611
630
|
|
|
612
631
|
res.send(payload)
|
|
613
632
|
})
|
|
@@ -616,15 +635,16 @@ test('error handler is triggered when a string is thrown from sync handler', t =
|
|
|
616
635
|
method: 'GET',
|
|
617
636
|
url: '/'
|
|
618
637
|
}, (err, res) => {
|
|
619
|
-
t.
|
|
620
|
-
t.
|
|
638
|
+
t.assert.ifError(err)
|
|
639
|
+
t.assert.strictEqual(res.payload, payload)
|
|
640
|
+
testDone()
|
|
621
641
|
})
|
|
622
642
|
})
|
|
623
643
|
|
|
624
644
|
test('status code should be set to 500 and return an error json payload if route handler throws any non Error object expression', async t => {
|
|
625
645
|
t.plan(2)
|
|
626
646
|
const fastify = Fastify()
|
|
627
|
-
t.
|
|
647
|
+
t.after(() => fastify.close())
|
|
628
648
|
|
|
629
649
|
fastify.get('/', () => {
|
|
630
650
|
/* eslint-disable-next-line */
|
|
@@ -633,14 +653,14 @@ test('status code should be set to 500 and return an error json payload if route
|
|
|
633
653
|
|
|
634
654
|
// ----
|
|
635
655
|
const reply = await fastify.inject({ method: 'GET', url: '/' })
|
|
636
|
-
t.
|
|
637
|
-
t.
|
|
656
|
+
t.assert.strictEqual(reply.statusCode, 500)
|
|
657
|
+
t.assert.strictEqual(JSON.parse(reply.body).foo, 'bar')
|
|
638
658
|
})
|
|
639
659
|
|
|
640
660
|
test('should preserve the status code set by the user if an expression is thrown in a sync route', async t => {
|
|
641
661
|
t.plan(2)
|
|
642
662
|
const fastify = Fastify()
|
|
643
|
-
t.
|
|
663
|
+
t.after(() => fastify.close())
|
|
644
664
|
|
|
645
665
|
fastify.get('/', (_, rep) => {
|
|
646
666
|
rep.status(501)
|
|
@@ -651,15 +671,15 @@ test('should preserve the status code set by the user if an expression is thrown
|
|
|
651
671
|
|
|
652
672
|
// ----
|
|
653
673
|
const reply = await fastify.inject({ method: 'GET', url: '/' })
|
|
654
|
-
t.
|
|
655
|
-
t.
|
|
674
|
+
t.assert.strictEqual(reply.statusCode, 501)
|
|
675
|
+
t.assert.strictEqual(JSON.parse(reply.body).foo, 'bar')
|
|
656
676
|
})
|
|
657
677
|
|
|
658
678
|
test('should trigger error handlers if a sync route throws any non-error object', async t => {
|
|
659
679
|
t.plan(2)
|
|
660
680
|
|
|
661
681
|
const fastify = Fastify()
|
|
662
|
-
t.
|
|
682
|
+
t.after(() => fastify.close())
|
|
663
683
|
|
|
664
684
|
const throwable = 'test'
|
|
665
685
|
const payload = 'error'
|
|
@@ -669,19 +689,19 @@ test('should trigger error handlers if a sync route throws any non-error object'
|
|
|
669
689
|
})
|
|
670
690
|
|
|
671
691
|
fastify.setErrorHandler((err, req, res) => {
|
|
672
|
-
t.
|
|
692
|
+
t.assert.strictEqual(err, throwable)
|
|
673
693
|
res.code(500).send(payload)
|
|
674
694
|
})
|
|
675
695
|
|
|
676
696
|
const reply = await fastify.inject({ method: 'GET', url: '/' })
|
|
677
|
-
t.
|
|
697
|
+
t.assert.strictEqual(reply.statusCode, 500)
|
|
678
698
|
})
|
|
679
699
|
|
|
680
700
|
test('should trigger error handlers if a sync route throws undefined', async t => {
|
|
681
701
|
t.plan(1)
|
|
682
702
|
|
|
683
703
|
const fastify = Fastify()
|
|
684
|
-
t.
|
|
704
|
+
t.after(() => fastify.close())
|
|
685
705
|
|
|
686
706
|
fastify.get('/', function async (req, reply) {
|
|
687
707
|
// eslint-disable-next-line no-throw-literal
|
|
@@ -689,13 +709,13 @@ test('should trigger error handlers if a sync route throws undefined', async t =
|
|
|
689
709
|
})
|
|
690
710
|
|
|
691
711
|
const reply = await fastify.inject({ method: 'GET', url: '/' })
|
|
692
|
-
t.
|
|
712
|
+
t.assert.strictEqual(reply.statusCode, 500)
|
|
693
713
|
})
|
|
694
714
|
|
|
695
|
-
test('setting content-type on reply object should not hang the server case 1', t => {
|
|
715
|
+
test('setting content-type on reply object should not hang the server case 1', (t, testDone) => {
|
|
696
716
|
t.plan(2)
|
|
697
717
|
const fastify = Fastify()
|
|
698
|
-
t.
|
|
718
|
+
t.after(() => fastify.close())
|
|
699
719
|
|
|
700
720
|
fastify.get('/', (req, reply) => {
|
|
701
721
|
reply
|
|
@@ -708,15 +728,16 @@ test('setting content-type on reply object should not hang the server case 1', t
|
|
|
708
728
|
url: '/',
|
|
709
729
|
method: 'GET'
|
|
710
730
|
}, (err, res) => {
|
|
711
|
-
t.
|
|
712
|
-
t.
|
|
731
|
+
t.assert.ifError(err)
|
|
732
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
733
|
+
testDone()
|
|
713
734
|
})
|
|
714
735
|
})
|
|
715
736
|
|
|
716
737
|
test('setting content-type on reply object should not hang the server case 2', async t => {
|
|
717
738
|
t.plan(1)
|
|
718
739
|
const fastify = Fastify()
|
|
719
|
-
t.
|
|
740
|
+
t.after(() => fastify.close())
|
|
720
741
|
|
|
721
742
|
fastify.get('/', (req, reply) => {
|
|
722
743
|
reply
|
|
@@ -731,7 +752,7 @@ test('setting content-type on reply object should not hang the server case 2', a
|
|
|
731
752
|
url: '/',
|
|
732
753
|
method: 'GET'
|
|
733
754
|
})
|
|
734
|
-
t.
|
|
755
|
+
t.assert.deepStrictEqual({
|
|
735
756
|
error: 'Internal Server Error',
|
|
736
757
|
message: 'Attempted to send payload of invalid type \'object\'. Expected a string or Buffer.',
|
|
737
758
|
statusCode: 500,
|
|
@@ -739,16 +760,14 @@ test('setting content-type on reply object should not hang the server case 2', a
|
|
|
739
760
|
},
|
|
740
761
|
res.json())
|
|
741
762
|
} catch (error) {
|
|
742
|
-
t.
|
|
743
|
-
} finally {
|
|
744
|
-
await fastify.close()
|
|
763
|
+
t.assert.ifError(error)
|
|
745
764
|
}
|
|
746
765
|
})
|
|
747
766
|
|
|
748
|
-
test('setting content-type on reply object should not hang the server case 3', t => {
|
|
767
|
+
test('setting content-type on reply object should not hang the server case 3', (t, testDone) => {
|
|
749
768
|
t.plan(2)
|
|
750
769
|
const fastify = Fastify()
|
|
751
|
-
t.
|
|
770
|
+
t.after(() => fastify.close())
|
|
752
771
|
|
|
753
772
|
fastify.get('/', (req, reply) => {
|
|
754
773
|
reply
|
|
@@ -761,18 +780,19 @@ test('setting content-type on reply object should not hang the server case 3', t
|
|
|
761
780
|
url: '/',
|
|
762
781
|
method: 'GET'
|
|
763
782
|
}, (err, res) => {
|
|
764
|
-
t.
|
|
765
|
-
t.
|
|
783
|
+
t.assert.ifError(err)
|
|
784
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
785
|
+
testDone()
|
|
766
786
|
})
|
|
767
787
|
})
|
|
768
788
|
|
|
769
|
-
test('pipe stream inside error handler should not cause error', t => {
|
|
789
|
+
test('pipe stream inside error handler should not cause error', (t, testDone) => {
|
|
770
790
|
t.plan(3)
|
|
771
791
|
const location = path.join(__dirname, '..', 'package.json')
|
|
772
792
|
const json = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json')).toString('utf8'))
|
|
773
793
|
|
|
774
794
|
const fastify = Fastify()
|
|
775
|
-
t.
|
|
795
|
+
t.after(() => fastify.close())
|
|
776
796
|
|
|
777
797
|
fastify.setErrorHandler((_error, _request, reply) => {
|
|
778
798
|
const stream = fs.createReadStream(location)
|
|
@@ -787,8 +807,9 @@ test('pipe stream inside error handler should not cause error', t => {
|
|
|
787
807
|
url: '/',
|
|
788
808
|
method: 'GET'
|
|
789
809
|
}, (err, res) => {
|
|
790
|
-
t.
|
|
791
|
-
t.
|
|
792
|
-
t.
|
|
810
|
+
t.assert.ifError(err)
|
|
811
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
812
|
+
t.assert.deepStrictEqual(JSON.parse(res.payload), json)
|
|
813
|
+
testDone()
|
|
793
814
|
})
|
|
794
815
|
})
|