如何使用 Nestjs HTTP 模块正确处理使用 Axios 发出 HTTP 请求时返回的可观察值

use*_*257 2 node.js rxjs axios nestjs

我试图弄清楚如何使用 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);
      })            
    );
}
Run Code Online (Sandbox Code Playgroud)

我的 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
  })
})
Run Code Online (Sandbox Code Playgroud)

fri*_*doo 7

我建议返回一个仅发出请求的实际数据而不是AxiosResponse. 通常还建议直接在创建 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

调用该函数并订阅。

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