如何在NestJS非托管类中获取应用级配置?
在NestJS非托管类中获取应用级配置的解决方案
你需要在自定义异常类(非托管类)中获取应用配置,但无法直接注入ConfigService,同时不想用process.env破坏统一规范,这里提供几种可行方案:
方案一:抛出异常时传入配置参数
这是最直接且符合NestJS规范的方式,在托管服务中获取配置后,将参数传入异常构造函数。
1. 修改自定义异常类
import { HttpException, HttpStatus } from '@nestjs/common'; export class MyCustomException extends HttpException { constructor(message: string, serviceName: string, configA: string) { const payload = { serviceName, configA, message, }; super(payload, HttpStatus.BAD_REQUEST); } }
2. 在服务中抛出异常时传入配置
import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { MyCustomException } from './my-custom.exception'; @Injectable() export class DemoService { constructor(private readonly configService: ConfigService) {} execute() { // 从ConfigService获取配置 const serviceName = this.configService.get('SERVICE_NAME'); const configA = this.configService.get('CONFIG_A'); // 传入参数抛出异常 throw new MyCustomException('业务逻辑出错', serviceName, configA); } }
方案二:创建全局配置容器
通过单例类存储启动时初始化的配置,让非托管类可以直接访问。
1. 实现配置容器单例
// src/config/config.container.ts export class ConfigContainer { private static configStore: Record<string, any> = {}; // 初始化配置 static init(config: Record<string, any>) { this.configStore = { ...this.configStore, ...config }; } // 获取指定配置 static get(key: string): any { return this.configStore[key]; } }
2. 在应用启动时初始化容器
// src/main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ConfigService } from '@nestjs/config'; import { ConfigContainer } from './config/config.container'; async function bootstrap() { const app = await NestFactory.create(AppModule); const configService = app.get(ConfigService); // 将需要的配置注入容器 ConfigContainer.init({ SERVICE_NAME: configService.get('SERVICE_NAME'), CONFIG_A: configService.get('CONFIG_A'), }); await app.listen(3000); } bootstrap();
3. 在异常类中使用容器
import { HttpException, HttpStatus } from '@nestjs/common'; import { ConfigContainer } from './config/config.container'; export class MyCustomException extends HttpException { constructor(message: string) { const serviceName = ConfigContainer.get('SERVICE_NAME'); const configA = ConfigContainer.get('CONFIG_A'); const payload = { serviceName, configA, message, }; super(payload, HttpStatus.BAD_REQUEST); } }
方案三:通过全局异常过滤器注入配置
无需修改异常类,在全局异常过滤器中注入ConfigService,将配置添加到响应体中。
1. 实现全局异常过滤器
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common'; import { Response } from 'express'; import { ConfigService } from '@nestjs/config'; @Catch(HttpException) export class CustomExceptionFilter implements ExceptionFilter { constructor(private readonly configService: ConfigService) {} catch(exception: HttpException, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>(); const status = exception.getStatus(); const originalRes = exception.getResponse(); // 合并原始响应与配置信息 const responseBody = { ...(typeof originalRes === 'object' ? originalRes : { message: originalRes }), serviceName: this.configService.get('SERVICE_NAME'), configA: this.configService.get('CONFIG_A'), }; response.status(status).json(responseBody); } }
2. 在启动时注册全局过滤器
// src/main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { CustomExceptionFilter } from './filters/custom-exception.filter'; import { ConfigService } from '@nestjs/config'; async function bootstrap() { const app = await NestFactory.create(AppModule); const configService = app.get(ConfigService); // 注册全局过滤器并注入ConfigService app.useGlobalFilters(new CustomExceptionFilter(configService)); await app.listen(3000); } bootstrap();
3. 保持异常类简洁
import { HttpException, HttpStatus } from '@nestjs/common'; export class MyCustomException extends HttpException { constructor(message: string) { super(message, HttpStatus.BAD_REQUEST); } }
内容的提问来源于stack exchange,提问作者roloenusa
相关产品推荐
相关产品推荐

