DEV Community

Cover image for How to integrate Sentry in NestJS
Marcelo Zapatta
Marcelo Zapatta

Posted on

How to integrate Sentry in NestJS

Hi guys, how are you? As Sentry does not have native support for the NestJS framework, I have created this step-by-step guide on how to integrate it. There are some tutorials using Nest's Interceptors, but the correct approach would be to use ExceptionFilters because Sentry only captures Exceptions, and it makes the code much simpler and easier to configure 😊

1. First, create a project in Sentry as NodeJS

Sentry page to create a project

2. Save the URL generated in the DNS section:

Location in Sentry to get the DNS URL

3. Install the dependencies

yarn add @sentry/node @sentry/tracing

// or

npm install @sentry/node @sentry/tracing
Enter fullscreen mode Exit fullscreen mode

4. Include a SENTRY_DNS key in your .env file containing the URL of your project:

Use the URL obtained in step 2 after generating the project

SENTRY_DNS=https://xxx@xxx.ingest.sentry.io/xxx
Enter fullscreen mode Exit fullscreen mode

5. Create an ExceptionFilter

We will create an ExceptionFilter inside Nest. To do this, include a file called sentry.filter.ts in the src folder with the following content:

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import * as Sentry from '@sentry/node';


@Catch()
export class SentryFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    Sentry.captureException(exception);
    super.catch(exception, host);
  }
}
Enter fullscreen mode Exit fullscreen mode

We are generating a generic ExceptionFilter that captures any type of Exception because the @Catch() decorator is empty. Also, we are extending it from BaseExceptionFilter, which is Nest's default class for handling exceptions. Therefore, we will not change the original behavior when an exception is thrown because the method of the parent class that handles exceptions is called at the end of the code: super.catch(exception, host);

6. Include the Sentry script in Nest's main.ts

Now simply call the Sentry initialization method and import the globally created ExceptionFilter in your main.ts file's bootstrap() method:

// other importers
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
import * as Sentry from '@sentry/node';
import { SentryFilter } from './filters/sentry.filter';


async function bootstrap() {
  // …
  // Initialize Sentry by passing the DNS included in the .env
  Sentry.init({
    dsn: process.env.SENTRY_DNS,
  });


  // Import the filter globally, capturing all exceptions on all routes
  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new SentryFilter(httpAdapter));

  // …
}


bootstrap();
Enter fullscreen mode Exit fullscreen mode

Done! Configuration completed 🎉🎉. This way, we are capturing all the exceptions in the system, but you can customize the ExceptionFilter to block and obtain only specific exceptions.

References

Sentry docs Node.JS: https://docs.sentry.io/platforms/node/
ExceptionFilters NestJS: https://docs.nestjs.com/exception-filtersHi guys, how are you? As Sentry does not have native support for the NestJS framework, I have created this step-by-step guide on how to integrate it. There are some tutorials using Nest's Interceptors, but the correct approach would be to use ExceptionFilters because Sentry only captures Exceptions, and it makes the code much simpler and easier to configure 😊

1. First, create a project in Sentry as NodeJS

Sentry page to create a project

2. Save the URL generated in the DNS section:

Location in Sentry to get the DNS URL

3. Install the dependencies

yarn add @sentry/node @sentry/tracing

// or

npm install @sentry/node @sentry/tracing
Enter fullscreen mode Exit fullscreen mode

4. Include a SENTRY_DNS key in your .env file containing the URL of your project:

Use the URL obtained in step 2 after generating the project

SENTRY_DNS=https://xxx@xxx.ingest.sentry.io/xxx
Enter fullscreen mode Exit fullscreen mode

5. Create an ExceptionFilter

We will create an ExceptionFilter inside Nest. To do this, include a file called sentry.filter.ts in the src folder with the following content:

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import * as Sentry from '@sentry/node';


@Catch()
export class SentryFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    Sentry.captureException(exception);
    super.catch(exception, host);
  }
}
Enter fullscreen mode Exit fullscreen mode

We are generating a generic ExceptionFilter that captures any type of Exception because the @Catch() decorator is empty. Also, we are extending it from BaseExceptionFilter, which is Nest's default class for handling exceptions. Therefore, we will not change the original behavior when an exception is thrown because the method of the parent class that handles exceptions is called at the end of the code: super.catch(exception, host);

6. Include the Sentry script in Nest's main.ts

Now simply call the Sentry initialization method and import the globally created ExceptionFilter in your main.ts file's bootstrap() method:

// other importers
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
import * as Sentry from '@sentry/node';
import { SentryFilter } from './filters/sentry.filter';


async function bootstrap() {
  // …
  // Initialize Sentry by passing the DNS included in the .env
  Sentry.init({
    dsn: process.env.SENTRY_DNS,
  });


  // Import the filter globally, capturing all exceptions on all routes
  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new SentryFilter(httpAdapter));

  // …
}


bootstrap();
Enter fullscreen mode Exit fullscreen mode

Done! Configuration completed 🎉🎉. This way, we are capturing all the exceptions in the system, but you can customize the ExceptionFilter to block and obtain only specific exceptions.

References

Sentry docs Node.JS: https://docs.sentry.io/platforms/node/
ExceptionFilters NestJS: https://docs.nestjs.com/exception-filters

Top comments (8)

Collapse
 
egor4ik325 profile image
Egor Zorin • Edited

Nice non-standard article, big thanks.

But instead of using BaseExceptionFilter.catch you should use BaseExceptionFilter.handleUnknownError.

Otherwise like using your code, you will get thousands of issues for standard exceptions (BadRequest, NotAuthorized, etc.)

@Catch()
export class SentryFilter extends BaseExceptionFilter {
  handleUnknownError(
    exception: any,
    host: ArgumentsHost,
    applicationRef: HttpServer<any, any> | AbstractHttpAdapter<any, any, any>,
  ): void {
    Sentry.captureException(exception);
    super.handleUnknownError(exception, host, applicationRef);
  }
}
Enter fullscreen mode Exit fullscreen mode

image

Collapse
 
marcelozapatta profile image
Marcelo Zapatta

That's a good example to consider, I'll update the post

Collapse
 
mzn1381 profile image
mzn1381

Hello
Are you sure that your codes are correct ? !!
I am writing codes exactly like you but they do not work !!.
you know it does not send any events or messages to sentry !!
I am confused !!
By the way , I have no idea because I think every things in my codes are
correct !
can you help me ?

Collapse
 
marcelozapatta profile image
Marcelo Zapatta

Hey, can you share some code to try to see what is the problem?

Collapse
 
harilal32576081 profile image
Harilal Chauhan • Edited

I have followed exactly but code is not working. nothing getting captured in sentry.

I used below setup and now everything is working fine.

visit this link : github.com/youssefadel77/nestjs-ex...

Collapse
 
careuno profile image
Carlos Merchán

how are you loading .env values?

process.env.SENTRY_DNS is undefined in main.ts

Collapse
 
marcelozapatta profile image
Marcelo Zapatta

Normally Nest.js will load the .env variables to process.env I just defined SENTRY_DNS there.

Collapse
 
sithumdev profile image
Sithum Basnayaka • Edited
import { ConfigService } from "@nestjs/config";
import * as Sentry from "@sentry/node";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const configService: ConfigService = app.get(ConfigService);

  Sentry.init({
    dsn: configService.get<string>("SENTRY_DNS"),
  });

}
Enter fullscreen mode Exit fullscreen mode

Have you tried ConfigService?