Simple Sentry setup on Nest framework.
Just explore the code for more details, especially the files in the sentry
folder.
To run this simple example, clone this repository and install the dependencies. Then copy .env.sample
to .env
and insert your own Sentry DNS.
You can find DNS for your project on Sentry.io in Project Setting / Client Keys.
Then run Nest using the usual command:
$ npm run start:debug
Once the Nest.js server is running you can go to http://localhost:3000/throw and it will create a sample error in your Sentry project.
Or you can run the E2E test:
$ npm run test:e2e
Below are some explanations on how to do a clean setup from scratch in your existing project.
Create a new Nest app using the CLI
$ nest new sentry-setup
Install Sentry
$ npm install --save @sentry/node @sentry/tracing
Create Sentry module, service and interceptor
$ nest g module sentry
$ nest g service sentry
$ nest g interceptor sentry/sentry
Create the SentryModule.forRoot()
method and add the Sentry.init(options)
in it.
Call the Sentry.Module.forRoot({...})
in the AppModule
.
Add the call to the Express requestHandler middleware in the AppModule
.
configure(consumer: MiddlewareConsumer): void {
consumer.apply(Sentry.Handlers.requestHandler()).forRoutes({
path: '*',
method: RequestMethod.ALL,
});
}
It is important to use that middleware otherwise the current Hub will be global and you will run into conflict as Sentry create a Hub by thread and Node.js is not multi-thread.
We want to initialize the transaction in the constructor of the service. You can customize your main transaction there.
Note that because I inject the Express request, the service must be request scoped. You can read more about that here.
@Injectable({ scope: Scope.REQUEST })
export class SentryService {
constructor(@Inject(REQUEST) private request: Request) {
// ... etc ...
}
}
The SentryInterceptor
will capture the exception and finish the transaction. Please also
note that it must be request scoped as we inject the SentryService
:
@Injectable({ scope: Scope.REQUEST })
export class SentryInterceptor implements NestInterceptor {
constructor(private sentryService: SentryService) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
// ... etc ...
}
}
As an example I added a span. This is not necessary, but it will just make the trace nicer in the performance tab of Sentry.
You can add more span anywhere in your application simply by injecting the SentryService
.