Skip to content

End request in async preHandler #677

@jsumners

Description

@jsumners

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed bug

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions