Skip to content

Commit

Permalink
feat(nestjs): Filter 4xx errors (#12695)
Browse files Browse the repository at this point in the history
Small change filtering expected errors from being reported to sentry in
the nestjs sdk.

Tested manually on my sample app.

Fixes #12523
  • Loading branch information
nicohrubec authored Jul 1, 2024
1 parent 3d4a3e0 commit 0d558de
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export class AppController1 {
return this.appService.testException(id);
}

@Get('test-expected-exception/:id')
async testExpectedException(@Param('id') id: string) {
return this.appService.testExpectedException(id);
}

@Get('test-outgoing-fetch-external-allowed')
async testOutgoingFetchExternalAllowed() {
return this.appService.testOutgoingFetchExternalAllowed();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import * as Sentry from '@sentry/nestjs';
import { makeHttpRequest } from './utils';

Expand Down Expand Up @@ -52,6 +52,10 @@ export class AppService1 {
throw new Error(`This is an exception with id ${id}`);
}

testExpectedException(id: string) {
throw new HttpException(`This is an expected exception with id ${id}`, HttpStatus.FORBIDDEN);
}

async testOutgoingFetchExternalAllowed() {
const fetchResponse = await fetch('http://localhost:3040/external-allowed');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';
import { waitForError, waitForTransaction } from '@sentry-internal/test-utils';

test('Sends exception to Sentry', async ({ baseURL }) => {
const errorEventPromise = waitForError('nestjs', event => {
Expand Down Expand Up @@ -28,3 +28,28 @@ test('Sends exception to Sentry', async ({ baseURL }) => {
span_id: expect.any(String),
});
});

test('Does not send expected exception to Sentry', async ({ baseURL }) => {
let errorEventOccurred = false;

waitForError('nestjs', event => {
if (!event.type && event.exception?.values?.[0]?.value === 'This is an expected exception with id 123') {
errorEventOccurred = true;
}

return event?.transaction === 'GET /test-expected-exception/:id';
});

const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => {
return transactionEvent?.transaction === 'GET /test-expected-exception/:id';
});

const response = await fetch(`${baseURL}/test-expected-exception/123`);
expect(response.status).toBe(403);

await transactionEventPromise;

await new Promise(resolve => setTimeout(resolve, 10000));

expect(errorEventOccurred).toBe(false);
});
7 changes: 7 additions & 0 deletions packages/node/src/integrations/tracing/nest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ export function setupNestErrorHandler(app: MinimalNestJsApp, baseFilter: NestJsE
const originalCatch = Reflect.get(target, prop, receiver);

return (exception: unknown, host: unknown) => {
const status_code = (exception as { status?: number }).status;

// don't report expected errors
if (status_code !== undefined && status_code >= 400 && status_code < 500) {
return originalCatch.apply(target, [exception, host]);
}

captureException(exception);
return originalCatch.apply(target, [exception, host]);
};
Expand Down

0 comments on commit 0d558de

Please sign in to comment.