Skip to content

Commit

Permalink
feat(nestjs): Handle GraphQL contexts in SentryGlobalFilter (#14320)
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst authored Nov 15, 2024
1 parent d41a04d commit 72751da
Showing 1 changed file with 23 additions and 33 deletions.
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 {
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

0 comments on commit 72751da

Please sign in to comment.