nestjs-pino icon indicating copy to clipboard operation
nestjs-pino copied to clipboard

[FEATURE REQUEST] Correct stack trace of a guard error in request errored pino-http's log

Open artursudnik opened this issue 3 years ago • 14 comments
trafficstars

The problem I am facing is similar to those described in this feature request. Despite after using LoggerErrorInterceptor I am getting the correct stack trace of errors thrown from controllers or services when an error is thrown from a guard, it behaves like LoggerErrorInterceptor was not used.

Describe the solution you'd like I am not sure if it is a bug or if additional functionality to be added. Probably this problem is caused by Interceptor not being called at all when application flow is broken on a guard level.

artursudnik avatar Aug 31 '22 21:08 artursudnik

can you provide minimal example repo with logs?

iamolegga avatar Sep 01 '22 07:09 iamolegga

@iamolegga sure, I'll isolate this

artursudnik avatar Sep 01 '22 07:09 artursudnik

@iamolegga I apologize for the delay. Here is this problem reproduced: https://github.com/artursudnik/nestjs-pino-issue.

artursudnik avatar Sep 05 '22 22:09 artursudnik

I can confirm this happens to me either. Have you came up with a workaround to it?

mattvgm avatar Oct 20 '22 21:10 mattvgm

No, unfortunately, I have not.

artursudnik avatar Oct 21 '22 00:10 artursudnik

Does it work properly with the original built-in logger?

iamolegga avatar Oct 21 '22 10:10 iamolegga

@iamolegga I need to double-check this. I guess yes though.

artursudnik avatar Oct 21 '22 12:10 artursudnik

Considering NestJS's request lifecycle, should this logic be in an interceptor? Wouldn't an exception filter be a better fit for this?

The same issue is happening for me. All errors except ones from guards are logged just fine.

eyalch avatar Dec 18 '22 00:12 eyalch

Wouldn't an exception filter be a better fit for this?

agree, we need to change this class to a filter and add tests to verify that it correctly catches and logs errors from different layers

iamolegga avatar Dec 20 '22 07:12 iamolegga

Same to me, but it only happens when i try to execute test scripts using jest+supertest. I am not sure how to fix it. @artursudnik Did you find out the solution?

magbeans avatar Jan 05 '23 17:01 magbeans

@happy-ruby

@artursudnik Did you find out the solution?

No, I have not.

artursudnik avatar Jan 06 '23 12:01 artursudnik

Okay thanks, what i fixed is that i switched logger.warn to logger.errror in exception cases. Then i could catch out the issue logs. That may be an alternative solution.

magbeans avatar Jan 06 '23 15:01 magbeans

As @eyalch pointed out, the problem is that interceptors run after guards. The solution is to add an exception filter to do this instead.

The following seems to work well; it's heavily based on the sample exception filter. I have not tested it in a fastify environment.

import {
  type ArgumentsHost,
  Catch,
  type ExceptionFilter,
  HttpException,
  InternalServerErrorException,
} from "@nestjs/common";
import type { HttpAdapterHost } from "@nestjs/core";

@Catch()
export class LoggerExceptionFilter implements ExceptionFilter {
  constructor(private readonly httpAdapterHost: HttpAdapterHost) {}

  catch(error: unknown, host: ArgumentsHost): void {
    // In certain situations `httpAdapter` might not be available in the
    // constructor method, thus we should resolve it here.
    const { httpAdapter } = this.httpAdapterHost;

    const response = host.switchToHttp().getResponse();

    const isFastifyResponse = response.raw !== undefined;

    if (isFastifyResponse) {
      response.raw.err = error;
    } else {
      response.err = error;
    }

    const httpException =
      error instanceof HttpException
        ? error
        : new InternalServerErrorException();

    httpAdapter.reply(
      response,
      httpException.getResponse(),
      httpException.getStatus()
    );
  }
}

Install during setup with:

const httpAdapterHost = app.get(HttpAdapterHost);
app.useGlobalFilters(new LoggerExceptionFilter(httpAdapterHost));

noahw3 avatar May 08 '23 19:05 noahw3

Thanks, @noahw3! Your solution should be considered as an official workaround for this issue.

artursudnik avatar Nov 28 '23 11:11 artursudnik