在 catchError RxJs 6 中调用全局 handleError 函数(从 RxJs 5 迁移)

Nic*_*las 2 rxjs ionic-framework angular

最近,我将 Ionic 3 项目升级到了 Ionic 4,通过这次升级,其他几个软件包也得到了更新(Angular 5 --> 8 和 RxJs 5.5 --> 6.5)。代码中所需的大部分更改进展顺利,但有一个更改我无法解决。

在我的一项服务中,我有一个执行 API 获取 (GET) 的函数。fetch( http GET) 中的任何错误都在全局错误函数中处理。在我旧的 Ionic 3 / RxJs 5~ 应用程序中,这是按如下方式完成的:

public fetch(): Observable<T[]> {
    let _path: string = this.path; 
    const url = this.getUrl(_path);

    return this.http
        .get(url, this.options)
        .catch(this.handleError);
}
Run Code Online (Sandbox Code Playgroud)

handleError函数在另一个服务中定义:

protected handleError(error: any) {
    const errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';

    this.logger.error('API endpoint: ' + this.path, errMsg);
    this.showErrorToast(); // not async in Ionic 3

    return Observable.throw(errMsg);
}
Run Code Online (Sandbox Code Playgroud)

在我的 Ionic 4 / RxJs 6 应用程序中,我尝试重新创建它,但没有成功。我已阅读并更改以下内容:

  • catch已弃用,应替换为catchError
  • Observable.throw也已弃用,应替换为throwError

所以我的新实现如下所示:

public fetch(): Observable<T[]> {
    let _path: string = this.path; 
    const url = this.getUrl(_path);

    return this.http
        .get(url, this.options)
        .pipe(
          catchError(() => { // this line is returning a error
            this.handleError;
          }
        ));  
}

protected handleError(error: any) {
    const errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';

    this.logger.error('API endpoint: ' + this.path, errMsg);
    this.showErrorToast(); // now async in Ionic 4

    return throwError(errMsg); // Changed this 
}
Run Code Online (Sandbox Code Playgroud)

但是,catchError(() =>返回以下错误:

Argument of type '() => void' is not assignable to parameter of type '(err: any, caught: Observable<Object>) => ObservableInput<any>'.
  Type 'void' is not assignable to type 'ObservableInput<any>'
Run Code Online (Sandbox Code Playgroud)

在尝试了其他几件事之后,我有点不知道如何解决这个问题,有什么想法或指示吗?

更新

在实施了一些建议的解决方案后,我不断收到与前一个相同但不同的错误:

 Type 'Observable<Object>' is not assignable to type 'Observable<T[]>'.
      The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?
        Type 'Object' is missing the following properties from type 'T[]': length, pop, push, concat, and 26 more
Run Code Online (Sandbox Code Playgroud)

因此,经过一番调查后,我想出了这个(使用 @theMayer 提出的解决方案):

我变了:

return this.http
    .get(url, this.options)
    .pipe(
      catchError(e => {
        this.handleError(e);
        return EMPTY;
      }
    ));
Run Code Online (Sandbox Code Playgroud)

到:

return this.http
        .get<T[]>(url, this.options)
        .pipe(
          catchError(e => {
            this.handleError(e);
            return EMPTY;
          }
        ));
Run Code Online (Sandbox Code Playgroud)

上述更改消除了错误,但我不确定这是正确的方法吗?fetch 函数将循环遍历定义 API 端点的多个其他服务。

the*_*yer 6

RxJs 6 中的语法更改让您陷入困境。错误消息看起来令人困惑,但它只说明您的错误处理程序必须返回一个可观察值(所有可管道操作符都必须返回)。然而,它并不关心 observable 是什么

因此,需要进行简单的重写(请注意,这EMPTY可能不完全是您所需要的,但它在我的代码中有效):

import { EMPTY } from 'rxjs';

public fetch(): Observable<T[]> {
    let _path: string = this.path; 
    const url = this.getUrl(_path);

    return this.http
        .get(url, this.options)
        .pipe(
          catchError(e => {        // need to capture the 'e' here...
            this.handleError(e);   // pass to your function
            return EMPTY;          // and return empty
          }
        ));  
}

protected handleError(error: any) {
    const errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';

    this.logger.error('API endpoint: ' + this.path, errMsg);
    this.showErrorToast(); // now async in Ionic 4
}
Run Code Online (Sandbox Code Playgroud)

删除这个:

返回抛出错误(errMsg);// 改变了这个