【问题标题】:How to correctly handle the observable returned when making a HTTP request with Axios using Nestjs HTTP module如何正确处理使用 Nestjs HTTP 模块向 Axios 发出 HTTP 请求时返回的 observable
【发布时间】:2023-03-07 14:43:01
【问题描述】:

我正在尝试弄清楚如何使用 Axios 和 Nestjs 框架发出 http 请求。在 Nest 文档中,它提供了流程的高级概述,但没有详细说明如何处理使用 axios 发出请求时返回的 Observable。

我正在使用相互 SSL 身份验证向 API 发出请求。我遇到了证书问题,我的请求失败了,但是没有抛出异常,控制器返回 200 ok,没有数据。当我注释掉所有 rxjs 代码并执行 axios.get(...).toPromise() 时,我发现了这一点。当我这样做时,我突然有一个完整的堆栈跟踪并引发了异常。

知道我在这里做错了什么吗?我应该把 catchError 块放在 map 块之前吗?

我的代码:

getRegistrationStatus(msisdn: string): Observable<AxiosResponse> {        
  return this.httpService.get(`${this.API_BASE_URL}/vb/registrationStatus?MSISDN=${msisdn}`)
    .pipe(            
      map(res => res.data),
      catchError(e => {
        throw new HttpException(e.statusText, e.status);
      })            
    );
}

我的 HTTP 模块/axios 配置:

HttpModule.register({
  timeout: 20000,
  validateStatus: () => true,
  httpsAgent: new Agent({
    ca: readFileSync(process.env.va_ca),
    keepAlive: false,        
    cert: readFileSync(process.env.va_cert),
    key: readFileSync(process.env.va_key),
    passphrase: process.env.va_passphrase
  })
})

【问题讨论】:

    标签: node.js rxjs axios nestjs


    【解决方案1】:

    axiosInstance 应该返回一个 Promise,而不是 Observable。

    【讨论】:

    • nestjs HTTP 模块将 axios 响应转换为 observable...
    • 对不起,我不明白你使用的是来自 nestjs 的服务,它将 axios 包装在 observable 中。
    【解决方案2】:

    我建议返回一个仅发出请求的实际数据而不是 AxiosResponse 的 Observable。通常还建议直接在创建 http 请求 (getRegistrationStatus) 的函数中处理 http 错误,而不是在调用/使用此函数的位置。

    // You could replace 'RegistrationStatus' with 'any' if you don't have a 
    // corresponding interface, but it's better to create one if you can
    getRegistrationStatus(msisdn: string): Observable<RegistrationStatus> {       
      return this.httpService.get(`${this.API_BASE_URL}/vb/registrationStatus?MSISDN=${msisdn}`)
        .pipe(            
          map(res => res.data),
          catchError(this.handleError<RegistrationStatus>(null)) // <- provide a default value on errors e.g. null           
        );
    }
    
    handleError<T>(result?: T) {
      return (error: AxiosError<any>): Observable<T> => {
        if (error.response) {
          // The request was made and the server responded with a status code
          // that falls out of the range of 2xx
          console.log(error.response.data);
          console.log(error.response.status);
          console.log(error.response.headers);
        } else if (error.request) {
          // The request was made but no response was received
          // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
          // http.ClientRequest in node.js
          console.log(error.request);
        } else {
          // Something happened in setting up the request that triggered an Error
          console.log('Error', error.message);
        }
        console.log(error.config);
    
        return of(result as T);
      }
    }
    

    调用函数并订阅。

    getRegistrationStatus(msisdn: string).subscribe(regStatus => {
      // regStatus will be null when an error occured
      console.log('registration status:', regStatus);
    })
    

    【讨论】:

      猜你喜欢
      • 2020-06-24
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      相关资源
      最近更新 更多