javascript - Como capturar exceções do NestJS lançadas em `forFeature` ou `forRoot`?


Configurei a validação da configuração conforme descrito na documentação do NestJS: https://docs.nestjs.com/techniques/configuration#schema-validation

A validação funciona como esperado, mas quando o meu ficheiro .env não é válido, estou a receber um erro simples, por exemplo:

Erro: Erro de validação da configuração: "FOO_BAR" é obrigatório em Function.forRoot (<PATH>\@nestjs\config\dist\config.module.js:44:27)

Este erro não é lançado pelo Nest, por isso a abordagem com globalFilter, que pode capturar todos os erros do Nest, não funciona: https://docs.nestjs.com/websockets/exception-filters#exception-filters

Como apanhar este erro para poder formatá-lo?

EDITAR: Esta é uma questão mais geral: Como capturar erros lançados dentro de forRoot, forFeature no NestJS?

Resposta #1

Isto é impossível. Porque o NestJS captura todos os erros e lida com eles quando o módulo é iniciado, exceto funções como onModuleInit. O erro que você vê no terminal na verdade é apenas como console.log. Este é o ficheiro que lida e mostra o log de erros quando o módulo inicia o ExceptionHandler.

import { RuntimeException } from './exceptions/runtime.exception';
import { Logger } from '@nestjs/common/services/logger.service';

export class ExceptionHandler {
  private static readonly logger = new Logger(ExceptionHandler.name);

  public handle(exception: RuntimeException | Error) {
    if (!(exception instanceof RuntimeException)) {
      ExceptionHandler.logger.error(exception.message, exception.stack);
      return;
    }
    ExceptionHandler.logger.error(exception.what(), exception.stack);
  }
}

Não se estende de Error e não lança novamente uma nova Exceção.

Portanto, não pode apanhar erros dentro de forRoot ou forFeature. mas como vê, porque está a registar, pode sobrescrever o logger no Nestjs, apanhar a mensagem de erro que precisa de formatar. Esta forma pode ser um pouco estúpida.

...
import { LoggerService, LogLevel } from '@nestjs/common/services/logger.service';
// Add custom logger
class CLogger implements LoggerService {
  log(message: any, ...optionalParams: any[]) {
    console.log(message);
  }
  error(message: any, ...optionalParams: any[]) {
    // check condition error at here
    console.error(message);
  }
  warn(message: any, ...optionalParams: any[]) {
    console.warn(message);
  }
  debug?(message: any, ...optionalParams: any[]) {
    console.debug(message);
  }
  verbose?(message: any, ...optionalParams: any[]) {
    console.debug(message);
  }
  fatal?(message: any, ...optionalParams: any[]) {
    console.debug(message);
  }
  setLogLevels?(levels: LogLevel[]) {
    // console.debug(message);
  }
}
// Import custom logger to NestJs at startup
...
    let app = await NestFactory.create(AppModule, {
      logger: new CLogger(),
    });
...