Created
January 19, 2021 10:42
-
-
Save RDeluxe/4b4746d373239b5e00698b4626dcccae to your computer and use it in GitHub Desktop.
Sentry Interceptor for Nestjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///// 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