fastify 3.27.2 → 4.0.0-alpha.1

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 (116) hide show
  1. package/README.md +5 -4
  2. package/build/build-error-serializer.js +27 -0
  3. package/build/build-validation.js +47 -35
  4. package/docs/Migration-Guide-V4.md +12 -0
  5. package/docs/Reference/ContentTypeParser.md +4 -0
  6. package/docs/Reference/Errors.md +51 -6
  7. package/docs/Reference/Hooks.md +4 -7
  8. package/docs/Reference/LTS.md +5 -4
  9. package/docs/Reference/Reply.md +23 -22
  10. package/docs/Reference/Request.md +1 -3
  11. package/docs/Reference/Routes.md +17 -10
  12. package/docs/Reference/Server.md +48 -63
  13. package/docs/Reference/TypeScript.md +11 -13
  14. package/docs/Reference/Validation-and-Serialization.md +28 -53
  15. package/docs/Type-Providers.md +257 -0
  16. package/examples/hooks.js +1 -1
  17. package/examples/simple-stream.js +18 -0
  18. package/fastify.d.ts +34 -22
  19. package/fastify.js +37 -35
  20. package/lib/configValidator.js +902 -1023
  21. package/lib/contentTypeParser.js +6 -16
  22. package/lib/context.js +36 -10
  23. package/lib/decorate.js +3 -1
  24. package/lib/error-handler.js +158 -0
  25. package/lib/error-serializer.js +257 -0
  26. package/lib/errors.js +43 -9
  27. package/lib/fourOhFour.js +31 -20
  28. package/lib/handleRequest.js +10 -13
  29. package/lib/hooks.js +14 -9
  30. package/lib/pluginOverride.js +0 -3
  31. package/lib/pluginUtils.js +3 -2
  32. package/lib/reply.js +28 -157
  33. package/lib/request.js +13 -10
  34. package/lib/route.js +131 -138
  35. package/lib/schema-controller.js +2 -2
  36. package/lib/schemas.js +27 -1
  37. package/lib/server.js +219 -116
  38. package/lib/symbols.js +4 -3
  39. package/lib/validation.js +2 -1
  40. package/lib/warnings.js +2 -12
  41. package/lib/wrapThenable.js +4 -11
  42. package/package.json +31 -35
  43. package/test/404s.test.js +243 -110
  44. package/test/500s.test.js +2 -2
  45. package/test/async-await.test.js +13 -69
  46. package/test/content-parser.test.js +32 -0
  47. package/test/context-config.test.js +52 -0
  48. package/test/custom-http-server.test.js +14 -7
  49. package/test/custom-parser-async.test.js +0 -65
  50. package/test/custom-parser.test.js +54 -121
  51. package/test/decorator.test.js +1 -3
  52. package/test/delete.test.js +5 -5
  53. package/test/encapsulated-error-handler.test.js +50 -0
  54. package/test/esm/index.test.js +0 -14
  55. package/test/fastify-instance.test.js +4 -4
  56. package/test/fluent-schema.test.js +4 -4
  57. package/test/get.test.js +3 -3
  58. package/test/helper.js +18 -3
  59. package/test/hooks-async.test.js +14 -47
  60. package/test/hooks.on-ready.test.js +9 -4
  61. package/test/hooks.test.js +58 -99
  62. package/test/http2/closing.test.js +5 -11
  63. package/test/http2/unknown-http-method.test.js +3 -9
  64. package/test/https/custom-https-server.test.js +12 -6
  65. package/test/input-validation.js +2 -2
  66. package/test/internals/handleRequest.test.js +3 -40
  67. package/test/internals/initialConfig.test.js +33 -12
  68. package/test/internals/reply.test.js +245 -3
  69. package/test/internals/request.test.js +13 -7
  70. package/test/internals/server.test.js +88 -0
  71. package/test/listen.test.js +84 -1
  72. package/test/logger.test.js +80 -40
  73. package/test/maxRequestsPerSocket.test.js +6 -4
  74. package/test/middleware.test.js +2 -25
  75. package/test/nullable-validation.test.js +51 -14
  76. package/test/plugin.test.js +31 -5
  77. package/test/pretty-print.test.js +22 -10
  78. package/test/reply-error.test.js +123 -12
  79. package/test/request-error.test.js +2 -5
  80. package/test/route-hooks.test.js +17 -17
  81. package/test/route-prefix.test.js +2 -1
  82. package/test/route.test.js +204 -20
  83. package/test/router-options.test.js +1 -1
  84. package/test/schema-examples.test.js +11 -5
  85. package/test/schema-feature.test.js +24 -19
  86. package/test/schema-serialization.test.js +9 -9
  87. package/test/schema-special-usage.test.js +14 -81
  88. package/test/schema-validation.test.js +9 -9
  89. package/test/skip-reply-send.test.js +1 -1
  90. package/test/stream.test.js +23 -12
  91. package/test/throw.test.js +8 -5
  92. package/test/type-provider.test.js +20 -0
  93. package/test/types/fastify.test-d.ts +10 -18
  94. package/test/types/import.js +2 -0
  95. package/test/types/import.ts +1 -0
  96. package/test/types/instance.test-d.ts +35 -14
  97. package/test/types/logger.test-d.ts +44 -15
  98. package/test/types/route.test-d.ts +8 -2
  99. package/test/types/schema.test-d.ts +2 -39
  100. package/test/types/type-provider.test-d.ts +417 -0
  101. package/test/validation-error-handling.test.js +8 -8
  102. package/test/versioned-routes.test.js +28 -16
  103. package/test/wrapThenable.test.js +7 -6
  104. package/types/content-type-parser.d.ts +17 -8
  105. package/types/hooks.d.ts +102 -59
  106. package/types/instance.d.ts +124 -104
  107. package/types/logger.d.ts +18 -104
  108. package/types/plugin.d.ts +10 -4
  109. package/types/reply.d.ts +16 -11
  110. package/types/request.d.ts +10 -5
  111. package/types/route.d.ts +42 -31
  112. package/types/schema.d.ts +1 -1
  113. package/types/type-provider.d.ts +99 -0
  114. package/types/utils.d.ts +1 -1
  115. package/lib/schema-compilers.js +0 -12
  116. package/test/emit-warning.test.js +0 -166
@@ -61,8 +61,8 @@ test('object or null body', t => {
61
61
  method: 'POST',
62
62
  url: '/',
63
63
  handler: (req, reply) => {
64
- t.equal(req.body, null)
65
- reply.code(200).send({ requestBody: req.body })
64
+ t.equal(req.body, undefined)
65
+ reply.code(200).send({ isUndefinedBody: req.body === undefined })
66
66
  },
67
67
  schema: {
68
68
  body: {
@@ -79,10 +79,8 @@ test('object or null body', t => {
79
79
  type: 'object',
80
80
  nullable: true,
81
81
  properties: {
82
- requestBody: {
83
- type: 'string',
84
- format: 'email',
85
- nullable: true
82
+ isUndefinedBody: {
83
+ type: 'boolean'
86
84
  }
87
85
  }
88
86
  }
@@ -100,7 +98,7 @@ test('object or null body', t => {
100
98
  }, (err, response, body) => {
101
99
  t.error(err)
102
100
  t.equal(response.statusCode, 200)
103
- t.same(JSON.parse(body), { requestBody: null })
101
+ t.same(JSON.parse(body), { isUndefinedBody: true })
104
102
  })
105
103
  })
106
104
  })
@@ -114,8 +112,8 @@ test('nullable body', t => {
114
112
  method: 'POST',
115
113
  url: '/',
116
114
  handler: (req, reply) => {
117
- t.equal(req.body, null)
118
- reply.code(200).send({ requestBody: req.body })
115
+ t.equal(req.body, undefined)
116
+ reply.code(200).send({ isUndefinedBody: req.body === undefined })
119
117
  },
120
118
  schema: {
121
119
  body: {
@@ -133,10 +131,8 @@ test('nullable body', t => {
133
131
  type: 'object',
134
132
  nullable: true,
135
133
  properties: {
136
- requestBody: {
137
- type: 'string',
138
- format: 'email',
139
- nullable: true
134
+ isUndefinedBody: {
135
+ type: 'boolean'
140
136
  }
141
137
  }
142
138
  }
@@ -154,7 +150,48 @@ test('nullable body', t => {
154
150
  }, (err, response, body) => {
155
151
  t.error(err)
156
152
  t.equal(response.statusCode, 200)
157
- t.same(JSON.parse(body), { requestBody: null })
153
+ t.same(JSON.parse(body), { isUndefinedBody: true })
154
+ })
155
+ })
156
+ })
157
+
158
+ test('Nullable body with 204', t => {
159
+ t.plan(5)
160
+
161
+ const fastify = Fastify()
162
+
163
+ fastify.route({
164
+ method: 'POST',
165
+ url: '/',
166
+ handler: (req, reply) => {
167
+ t.equal(req.body, undefined)
168
+ reply.code(204).send()
169
+ },
170
+ schema: {
171
+ body: {
172
+ type: 'object',
173
+ nullable: true,
174
+ properties: {
175
+ hello: {
176
+ type: 'string',
177
+ format: 'email'
178
+ }
179
+ }
180
+ }
181
+ }
182
+ })
183
+
184
+ fastify.listen(0, (err) => {
185
+ fastify.server.unref()
186
+ t.error(err)
187
+
188
+ sget({
189
+ method: 'POST',
190
+ url: 'http://localhost:' + fastify.server.address().port
191
+ }, (err, response, body) => {
192
+ t.error(err)
193
+ t.equal(response.statusCode, 204)
194
+ t.equal(body.length, 0)
158
195
  })
159
196
  })
160
197
  })
@@ -864,7 +864,7 @@ test('plugin metadata - dependencies (nested)', t => {
864
864
  })
865
865
 
866
866
  test('pluginTimeout', t => {
867
- t.plan(2)
867
+ t.plan(5)
868
868
  const fastify = Fastify({
869
869
  pluginTimeout: 10
870
870
  })
@@ -873,13 +873,35 @@ test('pluginTimeout', t => {
873
873
  })
874
874
  fastify.ready((err) => {
875
875
  t.ok(err)
876
- t.equal(err.code, 'ERR_AVVIO_PLUGIN_TIMEOUT')
876
+ t.equal(err.message,
877
+ "fastify-plugin: Plugin did not start in time: 'function (app, opts, done) { -- // to no call done on purpose'. You may have forgotten to call 'done' function or to resolve a Promise")
878
+ t.equal(err.code, 'FST_ERR_PLUGIN_TIMEOUT')
879
+ t.ok(err.cause)
880
+ t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
881
+ })
882
+ })
883
+
884
+ test('pluginTimeout - named function', { only: true }, t => {
885
+ t.plan(5)
886
+ const fastify = Fastify({
887
+ pluginTimeout: 10
888
+ })
889
+ fastify.register(function nameFunction (app, opts, done) {
890
+ // to no call done on purpose
891
+ })
892
+ fastify.ready((err) => {
893
+ t.ok(err)
894
+ t.equal(err.message,
895
+ "fastify-plugin: Plugin did not start in time: 'nameFunction'. You may have forgotten to call 'done' function or to resolve a Promise")
896
+ t.equal(err.code, 'FST_ERR_PLUGIN_TIMEOUT')
897
+ t.ok(err.cause)
898
+ t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
877
899
  })
878
900
  })
879
901
 
880
902
  test('pluginTimeout default', t => {
881
- t.plan(2)
882
- const clock = fakeTimer.install()
903
+ t.plan(5)
904
+ const clock = fakeTimer.install({ shouldClearNativeTimers: true })
883
905
 
884
906
  const fastify = Fastify()
885
907
  fastify.register(function (app, opts, done) {
@@ -889,7 +911,11 @@ test('pluginTimeout default', t => {
889
911
 
890
912
  fastify.ready((err) => {
891
913
  t.ok(err)
892
- t.equal(err.code, 'ERR_AVVIO_PLUGIN_TIMEOUT')
914
+ t.equal(err.message,
915
+ "fastify-plugin: Plugin did not start in time: 'function (app, opts, done) { -- // default time elapsed without calling done'. You may have forgotten to call 'done' function or to resolve a Promise")
916
+ t.equal(err.code, 'FST_ERR_PLUGIN_TIMEOUT')
917
+ t.ok(err.cause)
918
+ t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
893
919
  })
894
920
 
895
921
  t.teardown(clock.uninstall)
@@ -7,7 +7,7 @@ const Fastify = require('..')
7
7
  test('pretty print - static routes', t => {
8
8
  t.plan(2)
9
9
 
10
- const fastify = Fastify()
10
+ const fastify = Fastify({ exposeHeadRoutes: false })
11
11
  fastify.get('/test', () => {})
12
12
  fastify.get('/test/hello', () => {})
13
13
  fastify.get('/hello/world', () => {})
@@ -29,7 +29,7 @@ test('pretty print - static routes', t => {
29
29
  test('pretty print - parametric routes', t => {
30
30
  t.plan(2)
31
31
 
32
- const fastify = Fastify()
32
+ const fastify = Fastify({ exposeHeadRoutes: false })
33
33
  fastify.get('/test', () => {})
34
34
  fastify.get('/test/:hello', () => {})
35
35
  fastify.get('/hello/:world', () => {})
@@ -51,7 +51,7 @@ test('pretty print - parametric routes', t => {
51
51
  test('pretty print - mixed parametric routes', t => {
52
52
  t.plan(2)
53
53
 
54
- const fastify = Fastify()
54
+ const fastify = Fastify({ exposeHeadRoutes: false })
55
55
  fastify.get('/test', () => {})
56
56
  fastify.get('/test/:hello', () => {})
57
57
  fastify.post('/test/:hello', () => {})
@@ -75,7 +75,7 @@ test('pretty print - mixed parametric routes', t => {
75
75
  test('pretty print - wildcard routes', t => {
76
76
  t.plan(2)
77
77
 
78
- const fastify = Fastify()
78
+ const fastify = Fastify({ exposeHeadRoutes: false })
79
79
  fastify.get('/test', () => {})
80
80
  fastify.get('/test/*', () => {})
81
81
  fastify.get('/hello/*', () => {})
@@ -137,12 +137,14 @@ test('pretty print - commonPrefix', t => {
137
137
  const radixExpected = `└── /
138
138
  ├── hel
139
139
  │ ├── lo (GET)
140
+ │ │ lo (HEAD)
140
141
  │ └── icopter (GET)
142
+ │ icopter (HEAD)
141
143
  └── hello (PUT)
142
144
  `
143
145
  const flatExpected = `└── / (-)
144
- ├── helicopter (GET)
145
- └── hello (GET, PUT)
146
+ ├── helicopter (GET, HEAD)
147
+ └── hello (GET, PUT, HEAD)
146
148
  `
147
149
  t.equal(typeof radixTree, 'string')
148
150
  t.equal(typeof flatTree, 'string')
@@ -174,31 +176,41 @@ test('pretty print - includeMeta, includeHooks', t => {
174
176
  │ │ • (onTimeout) ["onTimeout()"]
175
177
  │ │ • (onRequest) ["anonymous()"]
176
178
  │ │ • (errorHandler) "defaultErrorHandler()"
179
+ │ │ lo (HEAD)
180
+ │ │ • (onTimeout) ["onTimeout()"]
181
+ │ │ • (onRequest) ["anonymous()"]
182
+ │ │ • (onSend) ["headRouteOnSendHandler()"]
183
+ │ │ • (errorHandler) "defaultErrorHandler()"
177
184
  │ └── icopter (GET)
178
185
  │ • (onTimeout) ["onTimeout()"]
179
186
  │ • (onRequest) ["anonymous()"]
180
187
  │ • (errorHandler) "defaultErrorHandler()"
188
+ │ icopter (HEAD)
189
+ │ • (onTimeout) ["onTimeout()"]
190
+ │ • (onRequest) ["anonymous()"]
191
+ │ • (onSend) ["headRouteOnSendHandler()"]
192
+ │ • (errorHandler) "defaultErrorHandler()"
181
193
  └── hello (PUT)
182
194
  • (onTimeout) ["onTimeout()"]
183
195
  • (onRequest) ["anonymous()"]
184
196
  • (errorHandler) "defaultErrorHandler()"
185
197
  `
186
198
  const flatExpected = `└── / (-)
187
- ├── helicopter (GET)
199
+ ├── helicopter (GET, HEAD)
188
200
  │ • (onTimeout) ["onTimeout()"]
189
201
  │ • (onRequest) ["anonymous()"]
190
202
  │ • (errorHandler) "defaultErrorHandler()"
191
- └── hello (GET, PUT)
203
+ └── hello (GET, PUT, HEAD)
192
204
  • (onTimeout) ["onTimeout()"]
193
205
  • (onRequest) ["anonymous()"]
194
206
  • (errorHandler) "defaultErrorHandler()"
195
207
  `
196
208
 
197
209
  const hooksOnlyExpected = `└── / (-)
198
- ├── helicopter (GET)
210
+ ├── helicopter (GET, HEAD)
199
211
  │ • (onTimeout) ["onTimeout()"]
200
212
  │ • (onRequest) ["anonymous()"]
201
- └── hello (GET, PUT)
213
+ └── hello (GET, PUT, HEAD)
202
214
  • (onTimeout) ["onTimeout()"]
203
215
  • (onRequest) ["anonymous()"]
204
216
  `
@@ -290,7 +290,7 @@ test('Support rejection with values that are not Error instances', t => {
290
290
  } else {
291
291
  t.equal(err, nonErr)
292
292
  }
293
- reply.send('error')
293
+ reply.code(500).send('error')
294
294
  })
295
295
 
296
296
  fastify.inject({
@@ -337,7 +337,7 @@ test('invalid schema - ajv', t => {
337
337
  })
338
338
  })
339
339
 
340
- test('should set the status code and the headers from the error object (from route handler)', t => {
340
+ test('should set the status code and the headers from the error object (from route handler) (no custom error handler)', t => {
341
341
  t.plan(4)
342
342
  const fastify = Fastify()
343
343
 
@@ -375,7 +375,7 @@ test('should set the status code and the headers from the error object (from cus
375
375
 
376
376
  fastify.setErrorHandler((err, request, reply) => {
377
377
  t.equal(err.message, 'ouch')
378
- t.equal(reply.raw.statusCode, 401)
378
+ t.equal(reply.raw.statusCode, 200)
379
379
  const error = new Error('kaboom')
380
380
  error.headers = { hello: 'world' }
381
381
  error.statusCode = 400
@@ -446,6 +446,74 @@ test('should throw an error if the custom serializer does not serialize the payl
446
446
  })
447
447
  })
448
448
 
449
+ test('should not set headers or status code for custom error handler', t => {
450
+ t.plan(7)
451
+
452
+ const fastify = Fastify()
453
+ fastify.get('/', function (req, reply) {
454
+ const err = new Error('kaboom')
455
+ err.headers = {
456
+ 'fake-random-header': 'abc'
457
+ }
458
+ reply.send(err)
459
+ })
460
+
461
+ fastify.setErrorHandler(async (err, req, res) => {
462
+ t.equal(res.statusCode, 200)
463
+ t.equal('fake-random-header' in res.headers, false)
464
+ return res.code(500).send(err.message)
465
+ })
466
+
467
+ fastify.inject({
468
+ method: 'GET',
469
+ url: '/'
470
+ }, (err, res) => {
471
+ t.error(err)
472
+ t.equal(res.statusCode, 500)
473
+ t.equal('fake-random-header' in res.headers, false)
474
+ t.equal(res.headers['content-length'], ('kaboom'.length).toString())
475
+ t.same(res.payload, 'kaboom')
476
+ })
477
+ })
478
+
479
+ test('error thrown by custom error handler routes to default error handler', t => {
480
+ t.plan(6)
481
+
482
+ const fastify = Fastify()
483
+
484
+ const error = new Error('kaboom')
485
+ error.headers = {
486
+ 'fake-random-header': 'abc'
487
+ }
488
+
489
+ fastify.get('/', function (req, reply) {
490
+ reply.send(error)
491
+ })
492
+
493
+ const newError = new Error('kabong')
494
+
495
+ fastify.setErrorHandler(async (err, req, res) => {
496
+ t.equal(res.statusCode, 200)
497
+ t.equal('fake-random-header' in res.headers, false)
498
+ t.same(err.headers, error.headers)
499
+
500
+ return res.send(newError)
501
+ })
502
+
503
+ fastify.inject({
504
+ method: 'GET',
505
+ url: '/'
506
+ }, (err, res) => {
507
+ t.error(err)
508
+ t.equal(res.statusCode, 500)
509
+ t.same(JSON.parse(res.payload), {
510
+ error: statusCodes['500'],
511
+ message: newError.message,
512
+ statusCode: 500
513
+ })
514
+ })
515
+ })
516
+
449
517
  // Issue 2078 https://github.com/fastify/fastify/issues/2078
450
518
  // Supported error code list: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
451
519
  const invalidErrorCodes = [
@@ -475,6 +543,34 @@ invalidErrorCodes.forEach((invalidCode) => {
475
543
  })
476
544
  })
477
545
 
546
+ test('error handler is triggered when a string is thrown from sync handler', t => {
547
+ t.plan(3)
548
+
549
+ const fastify = Fastify()
550
+
551
+ const throwable = 'test'
552
+ const payload = 'error'
553
+
554
+ fastify.get('/', function (req, reply) {
555
+ // eslint-disable-next-line no-throw-literal
556
+ throw throwable
557
+ })
558
+
559
+ fastify.setErrorHandler((err, req, res) => {
560
+ t.equal(err, throwable)
561
+
562
+ res.send(payload)
563
+ })
564
+
565
+ fastify.inject({
566
+ method: 'GET',
567
+ url: '/'
568
+ }, (err, res) => {
569
+ t.error(err)
570
+ t.equal(res.payload, payload)
571
+ })
572
+ })
573
+
478
574
  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 => {
479
575
  t.plan(2)
480
576
  const fastify = Fastify()
@@ -508,24 +604,39 @@ test('should preserve the status code set by the user if an expression is thrown
508
604
  })
509
605
 
510
606
  test('should trigger error handlers if a sync route throws any non-error object', async t => {
511
- t.plan(3)
607
+ t.plan(2)
512
608
 
513
609
  const fastify = Fastify()
514
610
 
515
- fastify.get('/', () => {
516
- /* eslint-disable-next-line */
517
- throw { foo: 'bar' }
611
+ const throwable = 'test'
612
+ const payload = 'error'
613
+
614
+ fastify.get('/', function async (req, reply) {
615
+ // eslint-disable-next-line no-throw-literal
616
+ throw throwable
518
617
  })
519
618
 
520
- fastify.setErrorHandler(async (error) => {
521
- t.ok(error)
522
- return error
619
+ fastify.setErrorHandler((err, req, res) => {
620
+ t.equal(err, throwable)
621
+ res.code(500).send(payload)
622
+ })
623
+
624
+ const reply = await fastify.inject({ method: 'GET', url: '/' })
625
+ t.equal(reply.statusCode, 500)
626
+ })
627
+
628
+ test('should trigger error handlers if a sync route throws undefined', async t => {
629
+ t.plan(1)
630
+
631
+ const fastify = Fastify()
632
+
633
+ fastify.get('/', function async (req, reply) {
634
+ // eslint-disable-next-line no-throw-literal
635
+ throw undefined
523
636
  })
524
637
 
525
- // ----
526
638
  const reply = await fastify.inject({ method: 'GET', url: '/' })
527
639
  t.equal(reply.statusCode, 500)
528
- t.equal(JSON.parse(reply.body).foo, 'bar')
529
640
  })
530
641
 
531
642
  test('setting content-type on reply object should not hang the server case 1', t => {
@@ -43,7 +43,7 @@ test('default 400 on request error with custom error handler', t => {
43
43
 
44
44
  fastify.setErrorHandler(function (err, request, reply) {
45
45
  t.type(request, 'object')
46
- t.type(request, fastify[kRequest])
46
+ t.type(request, fastify[kRequest].parent)
47
47
  reply
48
48
  .code(err.statusCode)
49
49
  .type('application/json; charset=utf-8')
@@ -132,10 +132,7 @@ test('default clientError handler ignores sockets in destroyed state', t => {
132
132
 
133
133
  const fastify = Fastify({
134
134
  bodyLimit: 1,
135
- keepAliveTimeout: 100,
136
- logger: {
137
- level: 'trace'
138
- }
135
+ keepAliveTimeout: 100
139
136
  })
140
137
  fastify.server.on('clientError', () => {
141
138
  // this handler is called after default handler, so we can make sure end was not called
@@ -7,11 +7,11 @@ const Fastify = require('../')
7
7
 
8
8
  process.removeAllListeners('warning')
9
9
 
10
- function endRouteHook (doneOrPayload, done) {
10
+ function endRouteHook (doneOrPayload, done, doneValue) {
11
11
  if (typeof doneOrPayload === 'function') {
12
- doneOrPayload()
12
+ doneOrPayload(doneValue)
13
13
  } else {
14
- done()
14
+ done(doneValue)
15
15
  }
16
16
  }
17
17
 
@@ -152,9 +152,9 @@ function testBeforeHandlerHook (hook) {
152
152
  const fastify = Fastify()
153
153
 
154
154
  fastify.post('/', {
155
- [hook]: (req, reply, done) => {
155
+ [hook]: (req, reply, doneOrPayload, done) => {
156
156
  req.hello = 'earth'
157
- done()
157
+ endRouteHook(doneOrPayload, done)
158
158
  }
159
159
  }, (req, reply) => {
160
160
  reply.send({ hello: req.hello })
@@ -190,8 +190,8 @@ function testBeforeHandlerHook (hook) {
190
190
  const fastify = Fastify()
191
191
 
192
192
  fastify.post('/', {
193
- [hook]: (req, reply, done) => {
194
- done(new Error('kaboom'))
193
+ [hook]: (req, reply, doneOrPayload, done) => {
194
+ endRouteHook(doneOrPayload, done, new Error('kaboom'))
195
195
  }
196
196
  }, (req, reply) => {
197
197
  reply.send(req.body)
@@ -221,7 +221,7 @@ function testBeforeHandlerHook (hook) {
221
221
 
222
222
  fastify.setErrorHandler(async (error, request, reply) => {
223
223
  t.same(error, myError, 'the error object throws by the user')
224
- reply.send({ this: 'is', my: 'error' })
224
+ return reply.code(500).send({ this: 'is', my: 'error' })
225
225
  })
226
226
 
227
227
  fastify.get('/', {
@@ -271,9 +271,9 @@ function testBeforeHandlerHook (hook) {
271
271
  const fastify = Fastify()
272
272
 
273
273
  fastify.post('/', {
274
- [hook]: (req, reply, done) => {
274
+ [hook]: (req, reply, doneOrPayload, done) => {
275
275
  reply.code(401)
276
- done(new Error('go away'))
276
+ endRouteHook(doneOrPayload, done, new Error('go away'))
277
277
  }
278
278
  }, (req, reply) => {
279
279
  reply.send(req.body)
@@ -302,10 +302,10 @@ function testBeforeHandlerHook (hook) {
302
302
  fastify.decorate('foo', 42)
303
303
 
304
304
  fastify.post('/', {
305
- [hook]: function (req, reply, done) {
305
+ [hook]: function (req, reply, doneOrPayload, done) {
306
306
  t.equal(this.foo, 42)
307
307
  this.foo += 1
308
- done()
308
+ endRouteHook(doneOrPayload, done)
309
309
  }
310
310
  }, function (req, reply) {
311
311
  reply.send({ foo: this.foo })
@@ -329,10 +329,10 @@ function testBeforeHandlerHook (hook) {
329
329
  fastify.decorate('foo', 42)
330
330
 
331
331
  fastify.post('/', {
332
- [hook]: [function (req, reply, done) {
332
+ [hook]: [function (req, reply, doneOrPayload, done) {
333
333
  t.equal(this.foo, 42)
334
334
  this.foo += 1
335
- done()
335
+ endRouteHook(doneOrPayload, done)
336
336
  }]
337
337
  }, function (req, reply) {
338
338
  reply.send({ foo: this.foo })
@@ -423,7 +423,7 @@ test('preParsing option should be called before preValidation hook', t => {
423
423
  })
424
424
 
425
425
  fastify.post('/', {
426
- preParsing: (req, reply, done) => {
426
+ preParsing: (req, reply, payload, done) => {
427
427
  req.called = true
428
428
  done()
429
429
  }
@@ -473,7 +473,7 @@ test('onRequest option should be called before preParsing', t => {
473
473
  t.plan(3)
474
474
  const fastify = Fastify()
475
475
 
476
- fastify.addHook('preParsing', (req, reply, done) => {
476
+ fastify.addHook('preParsing', (req, reply, payload, done) => {
477
477
  t.ok(req.called)
478
478
  done()
479
479
  })
@@ -503,7 +503,7 @@ test('onTimeout on route', t => {
503
503
  const fastify = Fastify({ connectionTimeout: 500 })
504
504
 
505
505
  fastify.get('/timeout', {
506
- async handler (request, reply) { },
506
+ handler (request, reply) { },
507
507
  onTimeout (request, reply, done) {
508
508
  t.pass('onTimeout called')
509
509
  done()
@@ -565,7 +565,8 @@ test('matches only /prefix/ with a / route - prefixTrailingSlash: "slash", igno
565
565
  test('calls onRoute only once when prefixing', async t => {
566
566
  t.plan(1)
567
567
  const fastify = Fastify({
568
- ignoreTrailingSlash: false
568
+ ignoreTrailingSlash: false,
569
+ exposeHeadRoutes: false
569
570
  })
570
571
 
571
572
  let onRouteCalled = 0