Skip to content

onError hook is called before errorHandler when error is thrown in onRequest hook #5469

Closed
@jillro

Description

@jillro

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.28

Plugin version

No response

Node.js version

16.20

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

Ubuntu 23.10

Description

const app = require('fastify')()
const request = require('supertest')

const onErrorHookHandler = jest.fn(async (req, res, error) => {})

app.addHook('onError', onErrorHookHandler)

app.setErrorHandler((error, req, res) => {
  if (error.message === 'unauthorized') {
    return res.code(401).send('unauthorized')
  }

  throw error
})

app.get('/should_not_be_logged', {
  onRequest: async () => {
    throw Error('unauthorized')
  }
}, async (req, res) => {
  res.send('OK')
})

app.get('/should_be_logged', {
  onRequest: async () => {
    throw Error('unhandled error')
  }
}, async (req, res) => {
  res.send('OK')
})

describe('Fastify handling errors in onRequest hooks', () => {
  beforeAll(async () => {
    return app.ready()
  })

  test('should call on Error hook for errors handled by custom error handler', async () => {
    const res = await request(app.server).get('/should_not_be_logged')

    expect(res.statusCode).toBe(401)
    expect(onErrorHookHandler).not.toHaveBeenCalled()
  })

  test('should call onError hook for unhandled errors', async () => {
    const res = await request(app.server).get('/should_be_logged')

    expect(res.statusCode).toBe(500)
    expect(onErrorHookHandler).toHaveBeenCalled()
  })
})

According to documentation onError hook will be executed only after the Custom Error Handler set by setErrorHandler has been executed, and only if the custom error handler sends an error back to the user (Note that the default error handler always sends the error back to the user).

In this case, the first test does not pass, and the onError hook is called before the custom error handler. This ruins the point of the onError hook, which according to documentation is useful if you need to do some custom error logging or add some specific header in case of error, because for logging (as it is used by the new Sentry plugin), it does not allow using the error handler to handle errors before they are logged.

Link to code that reproduces the bug

No response

Expected Behavior

The hook should be executed only after the Custom Error Handler set by setErrorHandler has been executed, and only if the custom error handler sends an error back to the user (Note that the default error handler always sends the error back to the user), even when the error has been thrown from a hook.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions