Nest 在调用“app.close()”时找不到 Sequelize 元素

Nest could not find Sequelize element when calling `app.close()`

我们有一个网络服务器 运行 Nest 8.0.8。使用给定的模块设置:

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      cache: true,
      validate,
      load: [configuration]
    }),
    SequelizeModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => config.get('db1'),
      inject: [ConfigService]
    }),
    SequelizeModule.forRootAsync({
      name: 'db2',
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => config.get('db2'),
      inject: [ConfigService],
    }),
  controllers: [...],
  providers: [...]
})

要启动应用程序,我们有这个 main.ts 文件:

async function bootstrap() {

  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(...)
  );

  useContainer(app.select(AppModule), { fallbackOnErrors: true });

  app.useGlobalPipes(
    new ValidationPipe({
      exceptionFactory: (errors) => new ValidationException(errors),
      transform: true,
      whitelist: true,
      validationError: {
        target: false,
        value: false
      }
    })
  );

  app.setGlobalPrefix('v1');

  app.useWebSocketAdapter(new RedisIoAdapter(app));

  app.enableCors({ origin: '*' });

  /**
   * When SIGTERM, run functions before shutting down
   */
  app.enableShutdownHooks();

  if (process.env.SETUP) {
    const service = app.get(FooService);
    await service.setup();
    await app.close();
    return;
  }

  await app.listen(3000, '0.0.0.0');
}

bootstrap().then();

当运行进行单元测试时,我们使用Nest自动配置数据库。最初在使用命令 SETUP=true nest start 初始化服务器后,将强制 Nest 不监听端口,并在 运行 service.setup() 之后提前 return。 (注意调用app.listen(...)app.close()函数时也会出现这个问题)

问题发生在调用 app.close() 我们希望 Nest 关闭所有连接,包括连接的 2 个数据库中的两个 SequelizeModule

不幸的是,Nest 关闭了第一个连接并尝试关闭第二个连接,但模块(我们怀疑)已经关闭。报错:

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:
Error: Nest could not find Sequelize element (this provider does not exist in the current context)
    at InstanceLinksHost.get (/Users/me/Repository/project_nest/node_modules/@nestjs/core/injector/instance-links-host.js:21:19)
    at Object.find (/Users/me/Repository/project_nest/node_modules/@nestjs/core/injector/module-ref.js:38:55)
    at Object.get (/Users/me/Repository/project_nest/node_modules/@nestjs/core/injector/module.js:345:28)
    at SequelizeCoreModule.<anonymous> (/Users/me/Repository/project_nest/node_modules/@nestjs/sequelize/dist/sequelize-core.module.js:81:47)
    at Generator.next (<anonymous>)
    at /Users/me/Repository/project_nest/node_modules/@nestjs/sequelize/dist/sequelize-core.module.js:20:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/me/Repository/project_nest/node_modules/@nestjs/sequelize/dist/sequelize-core.module.js:16:12)
    at SequelizeCoreModule.onApplicationShutdown (/Users/me/Repository/project_nest/node_modules/@nestjs/sequelize/dist/sequelize-core.module.js:80:16)
    at Object.callAppShutdownHook (/Users/me/Repository/project_nest/node_modules/@nestjs/core/hooks/on-app-shutdown.hook.js:51:35)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at NestApplication.callShutdownHook (/Users/me/Repository/project_nest/node_modules/@nestjs/core/nest-application-context.js:199:13)
    at NestApplication.close (/Users/me/Repository/project_nest/node_modules/@nestjs/core/nest-application-context.js:83:9)
    at bootstrap (/Users/me/Repository/project_nest/src/main.ts:143:5)

我们最初认为这是 Nest 的问题,但我们不确定。这在过去曾经有效,但不知何故,在更新后问题开始发生,由于其他依赖项的一些限制,我们无法降级库。

我想知道如何调试或解决问题,我们尝试调试应用程序但没有指出我们代码库中的问题。你能帮忙吗?

此致,佩德罗

您需要为第二个配置命名SequelizeModule。 您的情况示例

SequelizeModule.forRootAsync({
  name: 'db2',
  imports: [ConfigModule],
  useFactory: (config: ConfigService) => {
    name: 'db2',
    ...config.get('db2')
  },
  inject: [ConfigService],
}),

这个问题的原因是getConnectionToken函数,它用于从选项中按名称获取连接。如果您不使用特定名称,SequelizeModule 将在两个模块之间使用一个连接并将它们都关闭