Description
Description and expected behavior
I found scenario where the fastify plugin do not behave correctly, making fastify async fastify hooks to crash.
When using hooks and performing an async operation. Like a sample function that sleep 2s :
server.addHook('onSend', async (request, reply, payload) => {
await new Promise(r => setTimeout(r, 2000));
})
Screenshots
Example output:
{"level":40,"time":1694551858631,"pid":263378,"hostname":"YLDELL9552","reqId":"req-1","msg":"Reply was already sent, did you forget to \"return reply\" in the \"/api/model/paymentTerminal/findFirst?q=%7B%22include%22%3A%7B%22scope%22%3Atrue%7D%2C%22where%22%3A%7B%22id%22%3A%22slkrb0qi2cph3556q5abrss9%22%7D%7D\" (GET) route?"}
Error [ERR_HTTP_HEADERS_SENT]: Cannot write headers after they are sent to the client
at new NodeError (node:internal/errors:405:5)
at ServerResponse.writeHead (node:_http_server:345:11)
at safeWriteHead (/project/node_modules/.pnpm/fastify@4.22.2/node_modules/fastify/lib/reply.js:550:9)
at onSendEnd (/project/node_modules/.pnpm/fastify@4.22.2/node_modules/fastify/lib/reply.js:589:5)
at wrapOnSendEnd (/project/node_modules/.pnpm/fastify@4.22.2/node_modules/fastify/lib/reply.js:543:5)
at next (/project/node_modules/.pnpm/fastify@4.22.2/node_modules/fastify/lib/hooks.js:239:7)
at handleResolve (/project/node_modules/.pnpm/fastify@4.22.2/node_modules/fastify/lib/hooks.js:256:5) {
code: 'ERR_HTTP_HEADERS_SENT'
}
Environment (please complete the following information):
- ZenStack version: 1.0.0-beta.21
- (Fastify": "^4.22.2)
- (Prisma version: 5.2.0)
- ( Database type: MariaDB)
Additional context
I believe I found the root cause by Googling "fastify / hook / ERR_HTTP_HEADERS_SENT" (did not want to ping fastify project).
As the plugin uses the async function - fastify.all(${prefix}/*
, async (request, reply) => (see fastify/plugin.ts line 49), it would need to return the reply, as per the documentation say (https://fastify.dev/docs/latest/Reference/Routes/#async-await)
Quoted from the documentation
If you need it you can also send back the data to the user with reply.send. In this case do not forget to return reply or await reply in your async handler or you will introduce a race condition in certain situations.
I played with the source and think I was able to fix the issue. I'll try to submit the PR, which fix the problem.