-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Let's assume you have a plugin that supplies a preHandler hook. This plugin does some validation of incoming requests and returns an error response (401) if the request fails validation and terminates the request chain. With the traditional interface this looks like:
fastify.addHook('preHandler', function (req, reply, next) {
if (req.headers['foo'] === foo) return next()
req.code(401).send({error: 'nope'})
return
})But what do we do if the hook is an async function?
fastify.addHook('preHandler', async function (req, reply) {
if (req.headers['foo'] === foo) return
req.code(401).send({error: 'nope'})
return
})In this case we will get an error informing us that the reply has already been sent because 1. it has and 2. the request continues as if the hook didn't encounter an error despite undefined being returned. So let's modify it to satisfy the error check:
fastify.addHook('preHandler', async function (req, reply) {
if (req.headers['foo'] === foo) return
req.code(401).send({error: 'nope'})
return Error('make fastify realize an error occurred')
})Oops, we have a new problem. In this case we are creating an unhandled rejection.
It seems to me that there is no way to properly terminate a request at the preHandler step when using an async hook. I think there needs to be a way to do it to be consistent with the traditional interface.
Maybe async hooks can look for specific return values to determine what to do? For example, maybe this would terminate the request correctly?:
fastify.addHook('preHandler', async function (req, reply) {
if (req.headers['foo'] === foo) return
req.code(401).send({error: 'nope'})
return fastify.TERM_REQ
})Context
- node version: 8
- fastify version: 0.39.1
- os: Mac