我們使用 NestJS 作為基于微服務架構的 Typescript 框架。我們的一些部署是我們所說的“Kafka 作業人員”,運行代碼的 Pod 實際上并不公開任何 REST 端點,而只是監聽 kafka 主題并處理傳入事件。
問題是配置為希望捕獲任何拋出例外的全域例外過濾器沒有捕獲任何東西(我們最終得到 nods UnhandledPromiseRejection
)
例外過濾器基本上是這樣配置的(遵循 NestJS 檔案指南):
@Catch()
export class KafkaWorkerExceptionFilter implements ExceptionFilter {
private logger: AppLogger = new AppLogger(KafkaWorkerExceptionFilter.name);
catch(error: Error, host: ArgumentsHost): void {
this.logger.error('Uncaught exception', error);
}
}
我們對此類作業人員的控制器配置如下:
@Controller()
export class KafkaWorkerController {
private readonly logger = new AppLogger(KafkaWorkerController.name);
constructor(
) {
this.logger.log('Init');
}
@EventPattern(KafkaTopic.PiiRemoval)
async removePiiForTalent(data: IncomingKafkaMessage): Promise<void> {
await asyncDoSomething();
throw new Error('Business logic failed');
}
}
現在,我們希望全域例外過濾器能夠捕獲從控制器處理函式內部拋出的錯誤(以及真正的錯誤,從嵌套在其中的用于同步/異步操作的真實函式拋出)。這不會發生。
同樣,按照關于實作這種過濾器的 NestJS 檔案,我嘗試了很多方法,以及“注冊”該過濾器的方法組合,但沒有成功:
- 在頂級模塊定義中列為提供者
{ provide: APP_FILTER, useClass: KafkaWorkerExceptionFilter }
- 使用
@UseFilters(KafkaWorkerExceptionFilter)
控制器類上方的裝飾器 - 在使用kafka 配置之前/之后
app.useGlobalFilters(new KafkaWorkerExceptionFilter());
在檔案上使用嵌套main.ts
app.connectMicroservice(...)
就像我們如何在“kafka-worker”配置中初始化應用程式一樣,這里是main.ts
檔案:
async function bootstrap() {
const app = await NestFactory.create(KafkaWorkerAppModule, {
logger: ['error', 'warn', 'debug', 'log', 'verbose'],
});
app.use(Helmet());
app.useGlobalPipes(
new ValidationPipe({
disableErrorMessages: false,
whitelist: true,
transform: true,
}),
);
const logger: AppLogger = new AppLogger('Bootstrap');
const config: ConfigService = app.get(ConfigService);
app.connectMicroservice({
transport: Transport.KAFKA,
options: {
client: {
clientId: SECRET_VALUE,
brokers: [SECRET_HOST_ADDRESS],
ssl: true,
sasl: SOME_BOOLEAN_VALUE
? {
mechanism: 'plain',
username: SECRET_VALUE,
password: SECRET_VALUE,
}
: undefined,
},
consumer: {
allowAutoTopicCreation: false,
groupId: SECRET_VALUE,
},
},
});
await app.startAllMicroservices();
const port = config.servicePort || 3000;
await app.listen(port, () => {
logger.log(`Kafka Worker listening on port: ${port}`);
logger.log(`Environment: ${config.nodeEnv}`);
});
}
bootstrap();
uj5u.com熱心網友回復:
使用該connectMicroservice()
方法時,您正在創建一個Hybrid Application。
默認情況下,混合應用程式不會繼承為主(基于 HTTP)應用程式配置的全域管道、攔截器、防護和過濾器。要從主應用程式繼承這些配置屬性,請在 connectMicroservice() 呼叫的第二個引數(可選選項物件)中設定 inheritAppConfig 屬性,如下所示:
const microservice = app.connectMicroservice({ transport: Transport.TCP }, { inheritAppConfig: true });
因此,在您的情況下,您需要做的就是:
- 添加過濾器 - 在這些方法之一:
- 作為
APP_FILTER
一個KafkaWorkerAppModule
- 作為使用
app.useGlobalFilters(new KafkaWorkerExceptionFilter())
in的全域過濾器main.ts
@UseFilters(KafkaWorkerExceptionFilter)
在每個相關的提供者上使用——我會避免對全域過濾器使用這個
- 作為
- 將
inheritAppConfig
選項添加到app.connectMicroservice()
您的main.ts
:
app.connectMicroservice({
transport: Transport.KAFKA,
options: {
client: {
clientId: SECRET_VALUE,
brokers: [SECRET_HOST_ADDRESS],
ssl: true,
sasl: SOME_BOOLEAN_VALUE
? {
mechanism: 'plain',
username: SECRET_VALUE,
password: SECRET_VALUE,
}
: undefined,
},
consumer: {
allowAutoTopicCreation: false,
groupId: SECRET_VALUE,
},
},
},
{ inheritAppConfig: true }
);
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/494848.html
標籤:例外 巢穴 巢穴配置 卡夫卡斯 nestjs-异常过滤器
上一篇:如何在application.yaml/properties中為spring.jackson.deserialization.wrap-exceptions=false配置代碼手冊
下一篇:使用webclient過濾回應