middleware icon indicating copy to clipboard operation
middleware copied to clipboard

Sentry middleware captures HTTPException

Open alexgleason opened this issue 1 year ago • 8 comments

Hello! We are throwing an HTTPException in our code. hono/sentry captures this and creates an event in Sentry:

image

Is this the expected behavior? To me it seems that HTTPException shouldn't be captured, since it's actually a "handled" exception, in the sense that we are returning it manually (as an "escape-hatch") because we expect it to occur.

alexgleason avatar Apr 30 '24 17:04 alexgleason

We are trying to work around this by catching the error, but it's actually an instance of Error and not HTTPException, so neither of these solutions work:

app.use('*', sentryMiddleware({ dsn: Conf.sentryDsn, ignoreErrors: 'HTTPException' }));
app.onError((err) => {
  if (err instanceof HTTPException) {
    return err.getResponse();
  }
  throw err;
});

It's just a plain Error:

image

alexgleason avatar Apr 30 '24 17:04 alexgleason

@sam-lippert Can you see it?

yusukebe avatar Apr 30 '24 21:04 yusukebe

Also have this issue. I'm doing something like this

app.use(
  '*',
  sentry({
    ignoreErrors: ['Unauthorized']
  })
)

and throwing the error like so:

 const user = c.get('user')
  if (!user) {
    throw new HTTPException(401, { message: 'Unauthorized' })
  }

But for some reason the error is still being sent to Sentry.

dihmeetree avatar Jun 26 '24 17:06 dihmeetree

Bump! Any ideas @yusukebe @sam-lippert 🙂

dihmeetree avatar Jul 04 '24 21:07 dihmeetree

@dihmeetree This might be an issue with the toucan-js library, since the ignoreErrors property should pass through to it. Do you have the same issue if you try to use Toucan directly?

sam-lippert avatar Jul 05 '24 19:07 sam-lippert

There's also an update to the @hono/sentry middleware that can be applied to see if that works.

sam-lippert avatar Jul 08 '24 04:07 sam-lippert

@alexgleason It looks like ignoreErrors filters on the error's message property according to Sentry's docs. Does filtering work for you if you update the middleware version and set ignoreErrors: ['No pubkey provided']?

sam-lippert avatar Jul 08 '24 04:07 sam-lippert

I have the same problem and is eating my sentry quota away :/

masylum avatar Oct 03 '24 22:10 masylum

Having the same issue! We have different error messages keys when throwing the HTTPException. Would also love to filter out those errors by status code (x>=400, x<500).

~Maybe creating a custom HTTPException that does not extend an Error instance could work?:~

export declare class HTTPException {
    readonly res?: Response;
    readonly status: StatusCode;

    constructor(status?: StatusCode, options?: HTTPExceptionOptions);
    
    getResponse(): Response;
}

Edit: It won't work.

ubinatus avatar Oct 24 '24 18:10 ubinatus

Should be solved in #793. Allowing you to include which status codes from HTTPExceptions should be reported to Sentry:

  sentry({
    dsn: 'https://[email protected]/xxxxxx',
    
    // Includes only 500-599 status codes by default.
    includeStatusCodes: [{ min: 500, max: 599 }],
    
    // Or, you can combine a specific status code and a range.
    // includeStatusCodes: [500, { min: 503, max: 599 }],
    
    // If you want to exclude all HTTPExceptions, you can set an empty array.
  })

By default, if the error is an HTTPException instance, only those with status codes greater than 500 are reported to Sentry.

ubinatus avatar Oct 24 '24 21:10 ubinatus

PR is closed. But here are a few solutions suggested:

a) Clean the error

app.onError((err, c) => {
   ...

  if (err instanceof HTTPException) {
   // your custom logic to clear any particular `HttpException`s
    c.error = undefined
  }

   ...
})

b) Disable sentry

app.onError((err, c) => {
   ...

  if (err instanceof HTTPException) {
   // your custom logic to clear any particular `HttpException`s
    c.get('sentry').setEnabled(false)
  }

   ...
})

Both work if you don't have custom logic that depends on the error down the track.

See the PR for Sam's feedback in https://github.com/honojs/middleware/pull/793#discussion_r1817685914

ubinatus avatar Oct 26 '24 05:10 ubinatus

how do people work around this? I tried to apply the workarounds from the previous message and I still see the errors being reported to sentry:

const app = new Hono<AppType>()

app.onError((err, c) => {
	if (err instanceof HTTPException) {
		c.error = undefined
		return c.json({ error: err.message }, err.status)
	}

	return c.json({ error: err.message }, 500)
})
app.use("*", sentry())

masylum avatar Jan 23 '25 15:01 masylum

The solution is to not use this middleware. Just install Sentry like normal and call it where you need it.

alexgleason avatar Jan 23 '25 15:01 alexgleason

@yusukebe Sounds like the author has accepted a solution, can you close this?

sam-lippert avatar Jan 23 '25 16:01 sam-lippert

@sam-lippert Okay. Closing.

yusukebe avatar Jan 24 '25 09:01 yusukebe