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.92k stars 7.55k forks source link

process killed when exception happen in async function in nest 9.x.x #9936

Closed marefati110 closed 2 years ago

marefati110 commented 2 years ago

Is there an existing issue for this?

Current behavior

nestjs process exit when an error happern in an async function (without await) like this

i create a new project and use fasrify and also try to use errors.interceptor.ts https://docs.nestjs.com/interceptors but notworks

controller

import { Controller, Get } from '@nestjs/common';

import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  async getHello() {
    this.appService.getHello();
    return 'ok';
  }
}

service

import {
  BadGatewayException,
  BadRequestException,
  Injectable,
} from '@nestjs/common';

@Injectable()
export class AppService {
  async getHello() {
    throw new BadGatewayException();
    return 'Hello World!';
  }
}

ouput

/home/doctop/t/project-name/src/app.service.ts:10
    throw new BadGatewayException();
          ^
BadGatewayException: Bad Gateway
    at AppService.getHello (/home/doctop/t/project-name/src/app.service.ts:10:11)
    at AppController.getHello (/home/doctop/t/project-name/src/app.controller.ts:18:21)
    at /home/doctop/t/project-name/node_modules/@nestjs/core/router/router-execution-context.js:38:29
    at InterceptorsConsumer.transformDeferred (/home/doctop/t/project-name/node_modules/@nestjs/core/interceptors/interceptors-consumer.js:31:33)
    at /home/doctop/t/project-name/node_modules/@nestjs/core/interceptors/interceptors-consumer.js:15:53
    at Observable._subscribe (/home/doctop/t/project-name/node_modules/rxjs/src/internal/observable/defer.ts:55:15)
    at Observable._trySubscribe (/home/doctop/t/project-name/node_modules/rxjs/src/internal/Observable.ts:245:19)
    at /home/doctop/t/project-name/node_modules/rxjs/src/internal/Observable.ts:235:18
    at Object.errorContext (/home/doctop/t/project-name/node_modules/rxjs/src/internal/util/errorContext.ts:29:5)
    at Observable.subscribe (/home/doctop/t/project-name/node_modules/rxjs/src/internal/Observable.ts:221:5)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Minimum reproduction code

https://stackblitz.com/edit/nestjs-typescript-starter-3fwqre?file=src/app.controller.ts

Steps to reproduce

1 - oppen link https://stackblitz.com/edit/nestjs-typescript-starter-3fwqre?file=src/app.controller.ts 2 - yarn install 3 - yarn start 4 - refresh page

Expected behavior

Expected internal server error

Package

Other package

No response

NestJS version

9.0.3

Packages versions

{
  "name": "nest-typescript-starter",
  "private": true,
  "version": "1.0.0",
  "description": "Nest TypeScript starter repository",
  "license": "MIT",
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  "dependencies": {
    "@nestjs/common": "^9.0.0",
    "@nestjs/core": "^9.0.0",
    "@nestjs/platform-express": "^9.0.0",
    "@nestjs/platform-fastify": "^9.0.3",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.5.5"
  },
  "devDependencies": {
    "@nestjs/cli": "^9.0.0",
    "@nestjs/schematics": "^9.0.0",
    "@nestjs/testing": "^9.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "^28.1.4",
    "@types/node": "^18.0.3",
    "@types/supertest": "^2.0.12",
    "@typescript-eslint/eslint-plugin": "^5.30.5",
    "@typescript-eslint/parser": "^5.30.5",
    "eslint": "^8.19.0",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-prettier": "^4.2.1",
    "jest": "^28.1.2",
    "prettier": "^2.7.1",
    "source-map-support": "^0.5.21",
    "supertest": "^6.2.4",
    "ts-jest": "^28.0.5",
    "ts-loader": "^9.3.1",
    "ts-node": "^10.8.2",
    "tsconfig-paths": "^4.0.0",
    "typescript": "^4.7.4"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}

Node.js version

16

In which operating systems have you tested?

Other

No response

micalevisk commented 2 years ago

this is expected as you didn't use await (or handled any error) in the promise returned by AppService#getHello.

What is an unhandled promise rejection?

marefati110 commented 2 years ago

in same scenario with an other project with older version of nest i get this output

what is ExceptionsHandler is guess its not in version 9

[Nest] 84235  - 07/17/2022, 12:20:05 AM   ERROR [ExceptionsHandler] undefined is not iterable (cannot read property Symbol(Symbol.iterator))
TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
    at /home/doctop/doctop/doctop-nestjs/src/common/interceptors/reshape.interceptor.ts:77:39
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at /home/doctop/doctop/doctop-nestjs/src/common/interceptors/custom-serializer.interceptor.ts:57:16
[Nest] 84235  - 07/17/2022, 12:20:05 AM   ERROR [API] GET /v1/host/sitemap 500 333ms
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
BadGatewayException: Bad Gateway
    at HostService.hostSiteMap (/home/doctop/doctop/doctop-nestjs/src/app/site-generator/service/host.service.ts:77:11)
    at HostController.getHostSitMap (/home/doctop/doctop/doctop-nestjs/src/app/site-generator/controller/host.controller.ts:22:22)
    at /home/doctop/doctop/doctop-nestjs/node_modules/@nestjs/core/router/router-execution-context.js:38:29
    at InterceptorsConsumer.transformDeferred (/home/doctop/doctop/doctop-nestjs/node_modules/@nestjs/core/interceptors/interceptors-consumer.js:31:33)
    at /home/doctop/doctop/doctop-nestjs/node_modules/@nestjs/core/interceptors/interceptors-consumer.js:15:53
    at Observable._subscribe (/home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/observable/defer.ts:53:15)
    at Observable._trySubscribe (/home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/Observable.ts:244:19)
    at /home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/Observable.ts:234:18
    at Object.errorContext (/home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/util/errorContext.ts:29:5)
    at Observable.subscribe (/home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/Observable.ts:220:5)
    at doInnerSub (/home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/operators/mergeInternals.ts:71:40)
    at outerNext (/home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/operators/mergeInternals.ts:53:58)
    at OperatorSubscriber._this._next (/home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts:43:13)
    at OperatorSubscriber.Subscriber.next (/home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/Subscriber.ts:75:12)
    at /home/doctop/doctop/doctop-nestjs/node_modules/rxjs/src/internal/observable/innerFrom.ts:89:24
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

@micalevisk

micalevisk commented 2 years ago

are you using the same nodejs version in both? which version?

marefati110 commented 2 years ago

yes nodejs v16.16.0

@micalevisk

micalevisk commented 2 years ago

I guess we can't help you on that other project without the source.

For the repro you've shared, in node16 your app will crash because nestjs doesn't handle rejections on "floating" promises. And this is expected.

marefati110 commented 2 years ago

do you have and idea to how i can stop killing process on error ? change nodejs version or what ?... thanks @micalevisk

micalevisk commented 2 years ago

just add an await in there. Spend some time learning nodejs. Nestjs doesn't replaces Node.

marefati110 commented 2 years ago

I found that this code is used to prevent kill process in main.js

process.on('unhandledRejection', (error) => {
  console.error(error);
});

thsnk for your help

@micalevisk

micalevisk commented 2 years ago

another resource on this subject: Let It Crash: Best Practices for Handling Node.js Errors on Shutdown

marefati110 commented 2 years ago

another resource on this subject: Let It Crash: Best Practices for Handling Node.js Errors on Shutdown

thanks