Giter Site home page Giter Site logo

nestjs-sentry-example's Introduction

Hi there ๐Ÿ‘‹

Full-stack software engineer and architect, fractional CTO, running the elevator since 1999 in high performing consultancies. I have garnered a wide range of experience in many industries.

  • โš™๏ธ On a daily basis: .ts, .html, .css, Dockerfile, .tf, AWS, DO
  • ๐ŸŒฑ Iโ€™m currently learning C#, Python, MLOps, ...
  • ๐Ÿ’ฌ Ask me about outsourcing (๐Ÿ‡ต๐Ÿ‡ญ), product & team management
  • ๐Ÿ”ญ Currently working on many projects: gaming, retails, iot, real-estate
  • ๐Ÿ•ฐ๏ธ They trusted me: Nespresso, IOC, Laurastar, BATA, Swiss Lottery
  • โšก Grinding Kaggle, Roadmap.sh, and LeetCode

I would โค๏ธ to help you create your own business product. The best way to contact me is LinkedIn.

nestjs-sentry-example's People

Contributors

ericjeker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

nestjs-sentry-example's Issues

Using custom `SentryExceptionsFilter` is missing features of `BaseExceptionFilter`

Picking up from our discussion from #1 (comment) I've now tried the new Setup with. Thanks for your work!

While I first thought it's great to switch to an ExceptionFilter, I didn't know only one single ExceptionFilter will always be called, I thought one could pass on to the next ExceptionFilter. So with the current implementation, the features of the default BaseExceptionFilter will be lost.

I've also read, an ExceptionFilter should not throw an error. It actually makes sense to me, while it's not explicitly stated in the docs, the example also does not throw as well as the BaseExceptionsFilter.

Request Scoped DI Tree slows down the API significantly

Thank you for creating this.
I just wanted to warn that using this will cause pretty much all dependencies to be Request Scoped. I'd recommend not using this approach in production.

The Problem

By making the providers request-scoped, and injecting them to AppModule, API will instantiate new injection models for everything. This can slow down the API significantly.

Using request-scoped providers will have an impact on application performance. While Nest tries to cache as much metadata as possible, it will still have to create an instance of your class on each request. Hence, it will slow down your average response time and overall benchmarking result. Unless a provider must be request-scoped, it is strongly recommended that you use the default singleton scope.

The Solution

Use the context from the intercept method of the Exception Filter to start the Sentry Transaction and set the span.

Extract the request from the SentryInterceptor.

@Injectable()
export class SentryInterceptor implements NestInterceptor {
  constructor(private sentryService: SentryService) {}

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();

     const span = this.sentryService.getRequestSpan(request, {
      op: `Route Handler`,
    });

    return next.handle().pipe(
      catchError((error) => {
        // capture the error, you can filter out some errors here
        Sentry.captureException(
          error,
          span.getTraceContext(),
        );

        // throw again the error
        return throwError(() => error);
      }),
      finalize(() => {
        span.finish();
      }),
    );
  }
}

Modify the sentry.service to accept the request as a parameter, and return the scope:

@Injectable()
export class SentryService {
    public getRequestSpan(request: Request, spanContext: SpanContext) {
    const { method, headers, url } = request;

    const transaction = Sentry.startTransaction({
      name: `Route: ${method} ${url}`,
      op: 'transaction',
    });

    Sentry.getCurrentHub().configureScope((scope) => {
      scope.setSpan(transaction);

      scope.setContext('http', {
        method,
        url,
        headers,
      });
    });

    const span = Sentry.getCurrentHub().getScope().getSpan();

    span.startChild(spanContext);

    return span;
  }
}

Does not report errors in middleware and guards

Awesome work, thanks for sharing!

Just wanted to flag that due to the nature of NestJS request lifecycle this implementation will not report errors happening in your middlewares or guards.

This could be useful even with a stable implementation so that the performance monitoring tracks BadRequestExceptions for example.

Multiple parallel requests get jumbled together

Hello there. Thank you for this project, it was a great jumping off point to implement Sentry in NestJS for us.

There is a major issue with your implementation, however. Express can handle many request/responses at one time, when each request handler also makes async calls, so you cannot be using the same global hub since that will cause a huge jumbled mess.

If your app happens to never process multiple requests in parallel because you never hit it with multiple simultaneous requests, you've probably never noticed this.

But on apps receiving thousands of requests per minute, it becomes quite the huge mess.

You must use AsyncLocalStorage so that each request/response gets its own unique hub. See example here:

https://gist.github.com/jasonk/a06153476ae7fad41c527e321e318088

Add `LICENSE`

I guess it's just a little formality, is this OSS? Please add a LICENSE if so. Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.