Skip to content

Instantly share code, notes, and snippets.

@RDeluxe
Created January 19, 2021 10:42
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save RDeluxe/4b4746d373239b5e00698b4626dcccae to your computer and use it in GitHub Desktop.
Save RDeluxe/4b4746d373239b5e00698b4626dcccae to your computer and use it in GitHub Desktop.
Sentry Interceptor for Nestjs
///// SERVICE
import { Injectable } from '@nestjs/common';
import * as Sentry from '@sentry/node';
import config from '../../config';
import { SentryEntry } from './sentry.interceptor';
@Injectable()
export class SentryService {
private isInit = false;
constructor() {
if (config.sentry.dsn && config.sentry.env && config.sentry.release) {
Sentry.init({
dsn: config.sentry.dsn,
environment: config.sentry.env,
release: config.sentry.release,
});
this.isInit = true;
}
}
addLog(severity: Sentry.Severity, entry: SentryEntry, err: Error | string) {
if (!this.isInit) {
return;
}
Sentry.withScope(scope => {
scope.setExtra('body', entry.body);
scope.setExtra('origin', entry.origin);
scope.setExtra('action', entry.action);
scope.setLevel(severity);
typeof err === 'string'
? Sentry.captureMessage(err)
: Sentry.captureException(err);
});
}
}
///// INTERCEPTOR
import {
ExecutionContext,
Injectable,
NestInterceptor,
CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { SentryService } from './sentry.service';
import { Severity } from '@sentry/node';
export interface SentryEntry {
body: any;
origin: string;
action: string;
}
@Injectable()
export class SentryInterceptor implements NestInterceptor {
constructor(private readonly sentryService: SentryService) {}
async intercept(
context: ExecutionContext,
next: CallHandler,
): Promise<Observable<any>> {
const request = context.switchToHttp().getRequest();
const { method, body, url } = request;
const entry: SentryEntry = {
action: method,
origin: url,
body: body,
};
return next.handle().pipe(
catchError(err => {
const severity =
err.status && err.status < 500 ? Severity.Warning : Severity.Error;
this.sentryService.addLog(severity, entry, err);
throw err;
}),
);
}
}
//// MODULE
import { Module } from '@nestjs/common';
import { SentryInterceptor } from './sentry.interceptor';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { SentryService } from './sentry.service';
@Module({
imports: [],
providers: [
SentryService,
{
// This makes the interceptor global
provide: APP_INTERCEPTOR,
useClass: SentryInterceptor,
},
],
controllers: [],
exports: [SentryService],
})
export class SentryModule {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment