Prerequisites
Fastify version
4.0.3
Plugin version
No response
Node.js version
16.15.1
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
12.3.1
Description
After reply.callNotFound() has been called, request.context.config no longer contains the config object that the route was created with, and request.routerMethod and request.routerPath are undefined.
Since the context.config object seems to be commonly referred to as "route config", not "handler config", this is not what I expected. I expected that the config that the route was created with would be available regardless of whether the request was ultimately routed to the not found handler.
This happens because reply.callNotFound() internally sets the request's context property to the fourOhFour context, which contains an independent config.
|
reply.request.context = reply.context[kFourOhFourContext] |
Our use case: we set a unique routeId property in the config of each route that we then retrieve in an onResponse handler to send a metric to our monitoring system – allowing us to monitor the usage and performance of each route separately. See steps to reproduce below. However if reply.callNotFound() was called by the handler, this value is undefined.
I'd like to hear opinions about whether this should be considered a bug or expected behaviour.
- If it's considered a bug, I'm guessing that fixing this in-place would be considered a breaking change. Is that correct? If so I'd like to propose instead fixing it by adding the route config as a new property on
request and reply (e.g. request.routerConfig) that doesn't change when reply.callNotFound() is called. This would be nice because it would allow us to remove request.context and reply.context from the public API in a future major version (they have the disclaimer "A Fastify internal object. You should not use it directly or modify it" in the docs).
- If it's considered to be expected behaviour, then I think the docs should make this clear.
My preference is obviously for the former, but in either case I'd be happy to make a PR if it would be welcomed.
Steps to Reproduce
const fastify = require('fastify')()
fastify.addHook('onResponse', (request, reply, done) => {
console.log('onResponse routeId=', request.context.config.routeId)
console.log('onResponse routerPath=', request.routerPath)
console.log('onResponse routerMethod=', request.routerMethod)
done()
})
fastify.setNotFoundHandler((request, reply) => {
console.log('notFoundHandler routeId=', request.context.config.routeId)
console.log('notFoundHandler routerPath=', request.routerPath)
console.log('notFoundHandler routerMethod=', request.routerMethod)
reply.status(404).send()
})
fastify.route({
method: 'GET',
url: '/',
config: { routeId: 'myRoute' },
handler: (request, reply) => {
console.log('handler routeId=', request.context.config.routeId)
console.log('handler routerPath=', request.routerPath)
console.log('handler routerMethod=', request.routerMethod)
reply.callNotFound()
}
})
fastify.listen({ port: 3000 })
Expected Behavior
I would expect the router config to be available in the not found handler and in hooks, i.e.
handler routeId= myRoute
handler routerPath= /
handler routerMethod= GET
notFoundHandler routeId= myRoute
notFoundHandler routerPath= /
notFoundHandler routerMethod= GET
onResponse routeId= myRoute
onResponse routerPath= /
onResponse routerMethod= GET
Instead, it logs:
handler routeId= myRoute
handler routerPath= /
handler routerMethod= GET
notFoundHandler routeId= undefined
notFoundHandler routerPath= undefined
notFoundHandler routerMethod= undefined
onResponse routeId= undefined
onResponse routerPath= undefined
onResponse routerMethod= undefined
Prerequisites
Fastify version
4.0.3
Plugin version
No response
Node.js version
16.15.1
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
12.3.1
Description
After
reply.callNotFound()has been called,request.context.configno longer contains the config object that the route was created with, andrequest.routerMethodandrequest.routerPathare undefined.Since the
context.configobject seems to be commonly referred to as "route config", not "handler config", this is not what I expected. I expected that the config that the route was created with would be available regardless of whether the request was ultimately routed to the not found handler.This happens because
reply.callNotFound()internally sets the request'scontextproperty to the fourOhFour context, which contains an independentconfig.fastify/lib/reply.js
Line 689 in bf12b12
Our use case: we set a unique
routeIdproperty in theconfigof each route that we then retrieve in anonResponsehandler to send a metric to our monitoring system – allowing us to monitor the usage and performance of each route separately. See steps to reproduce below. However ifreply.callNotFound()was called by the handler, this value isundefined.I'd like to hear opinions about whether this should be considered a bug or expected behaviour.
requestandreply(e.g.request.routerConfig) that doesn't change whenreply.callNotFound()is called. This would be nice because it would allow us to removerequest.contextandreply.contextfrom the public API in a future major version (they have the disclaimer "A Fastify internal object. You should not use it directly or modify it" in the docs).My preference is obviously for the former, but in either case I'd be happy to make a PR if it would be welcomed.
Steps to Reproduce
Expected Behavior
I would expect the router config to be available in the not found handler and in hooks, i.e.
Instead, it logs: