如何使用NestJS的httpService捕获第三方API的错误响应?
解决方案
你使用的NestJS HttpService 底层基于Axios实现,完全可以通过拦截器或自定义封装的方式实现全局错误处理,无需每次请求手动编写catch逻辑。
方案1:注册Axios全局响应拦截器(最简便)
直接在应用初始化阶段给HttpService内置的Axios实例注册响应拦截器,统一处理所有请求的错误上报和异常抛出:
import { Module, OnModuleInit, Logger, InternalServerErrorException } from '@nestjs/common'; import { HttpModule, HttpService } from '@nestjs/axios'; import _ from 'lodash'; import util from 'util'; @Module({ imports: [HttpModule.register({})], // 其他模块、服务注册配置 }) export class AppModule implements OnModuleInit { private readonly logger = new Logger(AppModule.name); constructor(private readonly httpService: HttpService) {} onModuleInit() { // 获取HttpService内置的Axios实例 const axiosInstance = this.httpService.axiosRef; // 注册响应拦截器 axiosInstance.interceptors.response.use( // 成功请求直接返回响应 (response) => response, // 统一处理错误 (error) => { if (error.response) { const errorLog = _.pick(error.response, ['status', 'statusText', 'data']); this.logger.error( util.inspect( { ...errorLog, // 用户信息从请求配置的自定义meta字段取,避免上下文污染 user: error.config?.meta?.user ? { id: error.config.meta.user.id } : undefined, }, { showHidden: false, depth: null } ) ); } throw new InternalServerErrorException(); } ); } }
如果需要在错误日志中携带当前请求的用户ID,只需要在发起请求时把用户信息放到请求配置的自定义meta字段中即可:
const response = await this.httpService .request({ url: 'https://example.com/data', method: 'POST', // 自定义字段传递当前用户信息 meta: { user: currentUser }, }) .toPromise();
方案2:封装自定义HttpService
如果你希望和原生HttpService做隔离,更灵活地控制逻辑,可以继承原生HttpService重写请求方法,统一处理错误:
import { Injectable, Logger, InternalServerErrorException } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; import { catchError } from 'rxjs'; import _ from 'lodash'; import util from 'util'; @Injectable() export class CustomHttpService extends HttpService { private readonly logger = new Logger(CustomHttpService.name); request(config: any) { return super.request(config).pipe( catchError((error) => { if (error.response) { const errorLog = _.pick(error.response, ['status', 'statusText', 'data']); this.logger.error( util.inspect( { ...errorLog, user: config?.meta?.user ? { id: config.meta.user.id } : undefined, }, { showHidden: false, depth: null } ) ); } throw new InternalServerErrorException(); }) ); } }
之后在模块中注册CustomHttpService,所有业务代码直接注入该服务使用即可,无需额外处理错误。
内容的提问来源于stack exchange,提问作者user16172269
相关产品推荐
相关产品推荐

