Skip to content

fix(node): Avoid catching domain errors in request handler - #5627

Merged
AbhiPrasad merged 1 commit into
getsentry:masterfrom
mohd-akram:uncatch-error
Aug 30, 2022
Merged

AbhiPrasad merged 1 commit into
getsentry:masterfrom
mohd-akram:uncatch-error

Conversation

@mohd-akram

@mohd-akram mohd-akram commented Aug 23, 2022 •

Copy link
Copy Markdown
Contributor

According to the Node.js docs, domain errors are equivalent to an uncaught exception and therefore should not really be caught except to do some cleanup and then exit the process. Not doing so causes the process to potentially linger without being able to handle any request. Currently, the behavior is also erroneous because next can end up be called twice. This issue was discovered via fastify/middie#158.

Fixes #1922.

  • If you've added code that should be tested, please add tests.
  • Ensure your code lints and the test suite passes (yarn lint) & (yarn test).

@mohd-akram mohd-akram changed the title Avoid using domain in request handler Avoid catching domain errors in request handler Aug 23, 2022
@mohd-akram mohd-akram changed the title Avoid catching domain errors in request handler fix(node): Avoid catching domain errors in request handler Aug 23, 2022

@AbhiPrasad AbhiPrasad left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really just re-affirms that we should switch to async hooks soon enough, but for now I think we can :shipit:. I'll wait on the rest of my team members to take a look as well though.

@Lms24 Lms24 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mohd-akram thanks for opening this PR! The change LGTM

@AbhiPrasad
AbhiPrasad merged commit b57e8af into getsentry:master Aug 30, 2022
@mohd-akram
mohd-akram deleted the uncatch-error branch August 30, 2022 17:13
@abrenneke

abrenneke commented Sep 29, 2022 •

Copy link
Copy Markdown

It's a bit too late now but this actually ended up being a breaking change for us causing a P0 because we were accidentally relying on this behavior to catch exceptions... I guess we're this person >.< https://xkcd.com/1172/

@lobsterkatie

Copy link
Copy Markdown
Member

Best XKCD ever. 😄

Sorry you had to deal with the P0, though.

@ljearyscg

Copy link
Copy Markdown

by removing this it is no longer working with express when we have sentryErrorMiddleware that checks to see if we should handle the error. This will now always throw the exception.

image

@Lms24

Lms24 commented Oct 11, 2022 •

Copy link
Copy Markdown
Member

I @ljearyscg I'm not sure I'm following why this change impacted the errorhandler. If shouldHandlerError returns false, the exception should not be captured by Sentry. In both cases, the error is passed on via next(error):

if (shouldHandleError(error)) {
withScope(_scope => {
// For some reason we need to set the transaction on the scope again
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const transaction = (res as any).__sentry_transaction as Span;
if (transaction && _scope.getSpan() === undefined) {
_scope.setSpan(transaction);
}
const client = getCurrentHub().getClient<NodeClient>();
if (client && isAutoSessionTrackingEnabled(client)) {
// Check if the `SessionFlusher` is instantiated on the client to go into this branch that marks the
// `requestSession.status` as `Crashed`, and this check is necessary because the `SessionFlusher` is only
// instantiated when the the`requestHandler` middleware is initialised, which indicates that we should be
// running in SessionAggregates mode
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const isSessionAggregatesMode = (client as any)._sessionFlusher !== undefined;
if (isSessionAggregatesMode) {
const requestSession = _scope.getRequestSession();
// If an error bubbles to the `errorHandler`, then this is an unhandled error, and should be reported as a
// Crashed session. The `_requestSession.status` is checked to ensure that this error is happening within
// the bounds of a request, and if so the status is updated
if (requestSession && requestSession.status !== undefined) {
requestSession.status = 'crashed';
}
}
}
const eventId = captureException(error);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(res as any).sentry = eventId;
next(error);
});
return;
}
next(error);

If that is no longer the case, would you mind opening a new issue with an explanation and a reproduction example? Would be greatly appreciated, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Node: registering requestHandler changes error handling behaviour

7 participants