nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
66.91k stars 7.55k forks source link

Fastify adapter is not working #13861

Closed aswin567 closed 1 month ago

aswin567 commented 1 month ago

Is there an existing issue for this?

Current behavior

Issue

I am using fastify in my nest js application. The fastify adapter is used in the main.ts for the application. and customeExceptionFilter is added to a common moule and that module is imported in the app module of the respective application. The duty of the customeExceptionFilter is to catch the error and send its as a common error response. The current problem is the customeExceptionFilter is getting triggered but inside that instead of fastifyReply as response I am getting the node js native Server response. But the application working fine as expected (rest api aplication)

But this customeExceptionFilter make me feel like the fastify adpater isn ot working as expected or not. So i just want your help to solve the issues

Code Snippet

main.ts

import { Logger} from '@nestjs/common';
import { NestFactory } from '@nestjs/core';

import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app/app.module';
import * as dotenv from 'dotenv';
import { setupSwagger } from '@mybackedn-backend/common';

dotenv.config();

async function bootstrap() {
  const globalPrefix = process.env.ABCD;
  const port = process.env.ABCD;
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );

  // Set a global prefix if specified
  if (globalPrefix) {
    app.setGlobalPrefix(globalPrefix);
  }

  app.connectMicroservice({
    strategy: new FastifyAdapter(),
  });

  setupSwagger(app, process.env.ABC);
  await app.listen(port);
  Logger.log(
    `🚀 Application is running on: http://localhost:${port}/${globalPrefix}`
  );

customeExceptionFilter.ts

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
  BadRequestException,
  Logger
} from '@nestjs/common';
import { FastifyReply } from 'fastify';
import { ErrorResponseDto } from '../dtos/error-response.dto';
import { getErrorMessage } from '../consts/error-messages';
import { CommonErrorCodes } from '../enums/error-codes.enum';

@Catch()
export class CustomeExceptionFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<FastifyReply>();

    Logger.log('Response Object:', response); // Log the response object

    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    let errorResponse: any;

    if (exception instanceof BadRequestException) {
      const exceptionResponse = exception.getResponse() as any;

      errorResponse = {
        statusCode: HttpStatus.BAD_REQUEST,
        errorCode: CommonErrorCodes.VALIDATION_ERROR,
        errors: exceptionResponse.message || null,
        message: getErrorMessage(CommonErrorCodes.VALIDATION_ERROR),
      };
    } else if (exception instanceof HttpException) {
      const exceptionResponse = exception.getResponse() as any;

      errorResponse = {
        statusCode: status,
        errorCode: exceptionResponse.errorCode || CommonErrorCodes.INTERNAL_SERVER_ERROR,
        errors: exceptionResponse.errors || null,
        message: exceptionResponse.message || getErrorMessage(exceptionResponse.errorCode || CommonErrorCodes.INTERNAL_SERVER_ERROR),
      };
    } else {
      errorResponse = {
        statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
        errorCode: CommonErrorCodes.INTERNAL_SERVER_ERROR,
        message: getErrorMessage(CommonErrorCodes.INTERNAL_SERVER_ERROR),
        errors: null,
      };
    }

    const errorResponseDto = new ErrorResponseDto(
      errorResponse.statusCode,
      errorResponse.errorCode,
      errorResponse.message,
      errorResponse.errors,
    );

    response .status(status).send(errorResponseDto);

  }
}

Minimum reproduction code

https://stackblitz.com/edit/nestjs-typescript-starter-fh82bz?file=src%2Fcustome-exception.filter.ts

Steps to reproduce

Install required packages Run the api server with fastfyAdapter and CustomEExceptionFilter Using postman make the server through and error. You will get error like

response.status(status).send(errorResponseDto); // Fastify
                 ^
TypeError: response.status is not a function

Expected behavior

The response object i will get in the customExceptionFilter must be the type of fastifyReply and i can use the methods respectively

Package

Other package

No response

NestJS version

10.02

Packages versions

    "@fastify/static": "^7.0.4",
    "@nestjs/axios": "^3.0.2",
    "@nestjs/common": "^10.0.2",
    "@nestjs/config": "^3.2.3",
    "@nestjs/core": "^10.0.2",
    "@nestjs/microservices": "^10.3.10",
    "@nestjs/platform-express": "^10.0.2",
    "@nestjs/platform-fastify": "^10.3.10",
    "@nestjs/swagger": "^7.4.0",
    "@nestjs/terminus": "^10.2.3",
    "@nestjs/throttler": "^6.0.0",
    "@nestjs/typeorm": "^10.0.2",
    "axios": "^1.6.0",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.14.1",
    "dotenv": "^16.4.5",
    "fastify": "^4.28.1",
    "pg": "^8.12.0",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.8.0",
    "swagger-ui-express": "^5.0.1",
    "tslib": "^2.3.0",
    "typeorm": "^0.3.20"

Node.js version

20.15.1

In which operating systems have you tested?

Other

No response

kamilmysliwiec commented 1 month ago

Thank you for taking the time to submit your report! From the looks of it, this could be better discussed on our Discord. If you haven't already, please join here and send a new post in the #⁠ 🐈 nestjs-help forum. Make sure to include a link to this issue, so you don't need to write it all again. We have a large community of helpful members, who will assist you in getting this to work.