如何正确抛出错误以及Angular HTTP中不同错误捕获器的含义是啥[重复]

Posted

技术标签:

【中文标题】如何正确抛出错误以及Angular HTTP中不同错误捕获器的含义是啥[重复]【英文标题】:How to throwError properly and what are the meaning of different error catchers in Angular HTTP [duplicate]如何正确抛出错误以及Angular HTTP中不同错误捕获器的含义是什么[重复] 【发布时间】:2020-08-21 01:03:33 【问题描述】:

在决定在这里发布问题之前,我做了很多研究。我对 Angular(或一般)如何处理 HTTP 错误的了解非常模糊,因此我正在寻找一些澄清/建议。

为简单起见,假设我有一个休息 API GET http://example.com,它将随机返回 error: 'Error message'data: 'Data is available',其中 error 表示出现问题(请求成功完成,但存在一些内部错误) data 表示一切正常。

现在,据我了解,有两件事需要处理。第一件事是请求失败时的处理,例如网络错误、被CORS阻塞等,第二件事是处理成功的请求,但看是error还是data

TL;DR:如何将下面的 jQuery 转换为 Angular?

通常,使用 jQuery,我会这样做:

$.get('http://example.com').done(data => 

    if ('error' in data) console.log('Request completed, but there is an error in the remote server');
    else console.log('Everything completed successfully');

).fail(error => 

    console.log('Error while requesting data', error);

);

现在在 Angular 中,事情变得复杂了,无论我尝试什么,我似乎都无法抛出错误(所有函数都已正确导入):

//service.ts
    getStatus() 

        return this.http.get('https://test.com/')
        .pipe(
            map(data => 
                if ('error' in data) 
                    //I would like to throw an error that can be caught at subscribe(done, error) later
                    //But this rxjs won't throw anything, subscribe() will still resolve with done()
                    return throwError('Request completed, but there is an error in the remote server');
                
                return data;
            ),
            tap(data => 
                //Process the data, should not be called if map() throwError()?
            ,
            catchError(error => 
                //I assume this is where the HTTP request failed due to network, CORS, etc.
                return throwError('Error while requesting data');
            )
        );

    
//app.ts
    this.service.getStatus().subscribe(data => 

        //I expect this function to be called ONLY if there was no throwError(), but that wasn't the case
        //No matter what I try in `service.ts`, this will always be called

    , (error) => 

       //I expect this to call when throwError() is called from `service.ts` but it never happens

    );

我还阅读了另一个关于在 subscribe() 上使用 catch() 的建议,但 catch() 从来都不是订阅上的方法:

//app.ts
    this.service.getStatus().subscribe(data => 

        //I expect this function to be called ONLY if there was no throwError(), but that wasn't the case
        //No matter what I try in `service.ts`, this will always be called

    ).catch(error => 

        //This is not valid

    );

我尝试过的都没有奏效,管道中有多个地方我可以throwError(),但我不太确定它们的区别是什么(例如,service.ts 中的catchError()error 来自subscribe(success, error)app.ts

【问题讨论】:

这实际上会像我预期的那样抛出错误!你能把它作为一个答案,以便我能以某种方式接受它吗? 【参考方案1】:

对我来说似乎有点复杂。如果您不想实现 http 拦截器,我会简单地做这样的事情

//service.ts
  getStatus() 
    return this.http.get('http://www.test.com');
  

然后

//app.ts
    this.testService.getStatus()
      .subscribe(data => 
        if ('error' in data) 
          // process Error       
          return;
        
        // process data
        console.log(data);
      , error => 
        // http error
        console.log(error);
      );

对于 tap 操作符,它用于执行您想要的任何涉及数据或不涉及数据的操作(例如日志记录),但它始终会返回与其源相同的 observable。

【讨论】:

哇。这比我想象的要简单。我可能想多了。即使http()返回错误,tap()也会被激活吗? 不,如果返回一些数据就会触发。

以上是关于如何正确抛出错误以及Angular HTTP中不同错误捕获器的含义是啥[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Angular 4:如何正确处理应用程序级别的 http 错误作为 Observable 错误?

http.put 在使用 Chrome 但不是 IE 的 Angular 2 / Web API 中抛出错误

如何解决 Angular 单元测试错误:“在 afterAll\n[object ErrorEvent] 中抛出了一个错误”

在 Angular 应用程序中抛出错误

如何在可观察的地图中抛出错误(rxjs 6,ng6)

如果我的导入语句中没有 .js,Angular 2 会抛出错误