Skip to content

feat(nestjs): Handle non-HTTP contexts in SentryGlobalFilter - #24326

Open
tiagovilasboas wants to merge 2 commits into
getsentry:developfrom
tiagovilasboas:cursor/necord-sentry-global-filter-c128
Open

tiagovilasboas wants to merge 2 commits into
getsentry:developfrom
tiagovilasboas:cursor/necord-sentry-global-filter-c128

Conversation

@tiagovilasboas

@tiagovilasboas tiagovilasboas commented Sep 10, 2026 •

Copy link
Copy Markdown

NestJS custom execution contexts (getType() !== 'http', e.g. Necord Discord handlers) were falling through to the HTTP BaseExceptionFilter path, which expects an HTTP adapter and cannot reply on those hosts.

SentryGlobalFilter now treats any remaining non-HTTP context the same way after the existing GraphQL / RPC / WebSocket branches: capture unexpected errors, skip expected Nest control-flow exceptions, log Error instances, and return without delegating to HTTP handling.

The mechanism type follows the existing convention (auto.${contextType}.nestjs.global_filter). No library-specific dependency is added — context detection uses the string Nest already sets on the execution host.

Addresses review feedback from @s1gr1d (prefer contextType !== 'http' over a Necord-only branch).

Fixes #18472

@tiagovilasboas
tiagovilasboas marked this pull request as ready for review September 10, 2026 23:27
@tiagovilasboas
tiagovilasboas requested a review from a team as a code owner September 10, 2026 23:27
@tiagovilasboas
tiagovilasboas requested review from mydea and s1gr1d and removed request for a team September 10, 2026 23:27
@nicohrubec
nicohrubec self-requested a review September 11, 2026 07:49
@github-actions

Copy link
Copy Markdown
Contributor

👋 @mydea, @s1gr1d — Please review this PR when you get a chance!

Fixes getsentry#18472

Co-authored-by: Tiago Vilas Boas <tcarvalhovb@gmail.com>
@cursor
cursor Bot force-pushed the cursor/necord-sentry-global-filter-c128 branch from 0a5e99f to 00688ae Compare September 15, 2026 19:30

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 00688ae. Configure here.

}

return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Feat missing integration or E2E test

Medium Severity

This feat only adds unit tests for the new necord path in SentryGlobalFilter. The review rules require feat PRs to include at least one integration or E2E test, so the new context handling is not covered at that level. An integration test can drive a NestJS host with getType() returning necord and assert the captured event without adding necord or discord.js.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 00688ae. Configure here.

@github-actions

Copy link
Copy Markdown
Contributor

👋 @nicohrubec — Please review this PR when you get a chance!

@github-actions

Copy link
Copy Markdown
Contributor

👋 @mydea, @s1gr1d — Please review this PR when you get a chance!

@github-actions

Copy link
Copy Markdown
Contributor

👋 @nicohrubec — Please review this PR when you get a chance!

Comment thread packages/nestjs/src/setup.ts Outdated
Comment on lines +184 to +192
if (contextType === 'necord') {
if (!isExpectedError(exception)) {
captureException(exception, {
mechanism: {
handled: false,
type: 'auto.necord.nestjs.global_filter',
},
});
}

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.

Adding necord (a library) here would require adding all different library exceptions here and therefore adding a big catch-all.

It makes probably more sense to just check if the context is not http.

// Custom context types (necord, ...) run through ExternalContextCreator and have no HTTP adapter.
if (contextType !== 'http') {
  if (!isExpectedError(exception)) {
    captureException(exception, {
      mechanism: { handled: false, type: `auto.${contextType}.nestjs.global_filter` },
    });
  }
//...
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done in d069192 — replaced the Necord-only branch with a generic contextType !== 'http' path (dynamic mechanism type per context) and covered it with unit tests for necord and custom context types.

Replace the Necord-only branch with a generic contextType !== http path,
as requested in review. Mechanism type stays dynamic per context.
@tiagovilasboas tiagovilasboas changed the title feat(nestjs): Handle Necord contexts in SentryGlobalFilter feat(nestjs): Handle non-HTTP contexts in SentryGlobalFilter Sep 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

👋 @mydea — Please review this PR when you get a chance!

@github-actions

Copy link
Copy Markdown
Contributor

👋 @nicohrubec — Please review this PR when you get a chance!

this._logger.error(exception.message, exception.stack);
}

return;

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.

did you test the behavior for this? usually we rethrow exceptions to not interfere with user application behavior. however, there are exceptions for instance if you look at the rpc branch in this file. so not entirely sure this is correct, depends a bit on how the framework behaves here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes, tested it against real Nest (10.4.15): registered SentryGlobalFilter as APP_FILTER and ran a throwing handler through ExternalContextCreator with a necord context type, the same way necord wires its handlers.

The return doesn't swallow the error. ExternalExceptionsHandler.next() only uses the filter result if it's truthy, otherwise it falls back to ExternalExceptionFilter, which rethrows. So the caller still gets the original error, same as without the Sentry filter, and we capture it once. The rpc branch works the same way: returning there falls through to BaseRpcExceptionFilter, which still sends the error back to the client (checked with @nestjs/microservices 10.4.15). Nest master has the same fallback.

One side effect: the error gets logged twice (our _logger.error plus Nest's ExternalExceptionFilter). I can drop our log line in this branch if you'd like, and I can also add the framework-level test to the PR.

This branch has not been deployed

No deployments
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.

[Nestjs] Support necord contexts in SentryGlobalFilter

3 participants