Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(nestjs): Handle GraphQL contexts in SentryGlobalFilter #14320

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 23 additions & 33 deletions packages/nestjs/src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,35 +67,47 @@ export { SentryTracingInterceptor };
*/
class SentryGlobalFilter extends BaseExceptionFilter {
public readonly __SENTRY_INTERNAL__: boolean;
private readonly _logger: Logger;

public constructor(applicationRef?: HttpServer) {
super(applicationRef);
this.__SENTRY_INTERNAL__ = true;
this._logger = new Logger('ExceptionsHandler');
}

/**
* Catches exceptions and reports them to Sentry unless they are expected errors.
*/
public catch(exception: unknown, host: ArgumentsHost): void {
if (isExpectedError(exception)) {
return super.catch(exception, host);
// The BaseExceptionFilter does not work well in GraphQL applications.
// By default, Nest GraphQL applications use the ExternalExceptionFilter, which just rethrows the error:
// https://github.com/nestjs/nest/blob/master/packages/core/exceptions/external-exception-filter.ts
if (host.getType<'graphql'>() === 'graphql') {
// neither report nor log HttpExceptions
if (exception instanceof HttpException) {
throw exception;
}

if (exception instanceof Error) {
this._logger.error(exception.message, exception.stack);
}

captureException(exception);
throw exception;
}

if (!isExpectedError(exception)) {
captureException(exception);
}

captureException(exception);
return super.catch(exception, host);
}
}
Catch()(SentryGlobalFilter);
export { SentryGlobalFilter };

/**
* Global filter to handle exceptions and report them to Sentry.
*
* The BaseExceptionFilter does not work well in GraphQL applications.
* By default, Nest GraphQL applications use the ExternalExceptionFilter, which just rethrows the error:
* https://github.com/nestjs/nest/blob/master/packages/core/exceptions/external-exception-filter.ts
*
* The ExternalExceptinFilter is not exported, so we reimplement this filter here.
* Global filter to handle exceptions in NestJS + GraphQL applications and report them to Sentry.
*/
class SentryGlobalGraphQLFilter {
Copy link
Member

Choose a reason for hiding this comment

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

should we deprecate this one then?

Copy link
Member Author

@lforst lforst Nov 15, 2024

Choose a reason for hiding this comment

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

First we wanna release it, then at some point deprecate. See #14292

private static readonly _logger = new Logger('ExceptionsHandler');
Expand Down Expand Up @@ -129,29 +141,7 @@ export { SentryGlobalGraphQLFilter };
*
* This filter is a generic filter that can handle both HTTP and GraphQL exceptions.
*/
class SentryGlobalGenericFilter extends SentryGlobalFilter {
public readonly __SENTRY_INTERNAL__: boolean;
private readonly _graphqlFilter: SentryGlobalGraphQLFilter;

public constructor(applicationRef?: HttpServer) {
super(applicationRef);
this.__SENTRY_INTERNAL__ = true;
this._graphqlFilter = new SentryGlobalGraphQLFilter();
}

/**
* Catches exceptions and forwards them to the according error filter.
*/
public catch(exception: unknown, host: ArgumentsHost): void {
if (host.getType<'graphql'>() === 'graphql') {
return this._graphqlFilter.catch(exception, host);
}

super.catch(exception, host);
}
}
Catch()(SentryGlobalGenericFilter);
export { SentryGlobalGenericFilter };
export const SentryGlobalGenericFilter = SentryGlobalFilter;

/**
* Service to set up Sentry performance tracing for Nest.js applications.
Expand Down
Loading