在Observable.interval()中捕获HTTP错误

时间:2019-02-06 13:58:42

标签: angular angular5

我有一个块,每小时运行一次给定的URL。基本上,现在,如果未找到该URL或通常以错误500响应,我将收到错误消息。该应用程序利用服务人员,但如果提供的网址存在(404/500触发以下消息),则可以正常工作:

Failed to load resource: net::ERR_INVALID_RESPONSE
ERROR Error: Uncaught (in promise): TypeError: Failed to register a ServiceWorker: An unknown error occurred when fetching the script.
TypeError: Failed to register a ServiceWorker: An unknown error occurred when fetching the script.
    at resolvePromise (zone.js:831)
    at eval (zone.js:741)
    at eval (zone.js:757)
    at ZoneDelegate.invoke (zone.js:391)
    at Object.onInvoke (core.js:4760)
    at ZoneDelegate.invoke (zone.js:390)
    at Zone.run (zone.js:150)
    at eval (zone.js:889)
    at ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:4751)

在我的控制台中。如何优雅地捕获错误?

Observable.interval(3000)
      .subscribe((data) => {
         this.http.get('http://localhost:87887/profile/1/') // doesnt exist
           .subscribe((data) => {
             this.pingStream.next(true);
           },
           err => {

             if (err.status == 500){
              this.pingStream.next(false);
             }
             else{
               this.pingStream.next(true);
             }

           }
           );
      });

2 个答案:

答案 0 :(得分:0)

您应将订阅逻辑与异步逻辑分开。

Observable.interval(3000)
      .pipe(
       mergeMap(() => make http call),
       catchError( e => this.pingStream.next(false)),
       map((data) => this.pingStream.next(true))
      )
      .subscribe();

mergemap将每3秒钟间隔一次,并对您想要的任何服务进行http调用。 catchError将为您正常处理该错误 map将接听成功的电话,并用该值做某事。 subscribe()只是激活了可观察对象。

答案 1 :(得分:0)

如果您希望链在错误后继续运行,从而使interval(3000)不断发光,则必须将catchError放在concatMap内(否则mergeMap也会起作用) 。然后,这取决于发生错误时要执行的操作。您可以通过返回EMPTY或将其变为next通知来忽略它:

import { EMPTY } from 'rxjs';
...

// Assuming you're using RxJS 6
interval(3000).pipe(
  concatMap(() => this.http.get('http://localhost:87887/profile/1/').pipe(
    catchError(error => {
      if (err.status == 500){
        this.pingStream.next(false);
      } else {
        this.pingStream.next(true);
      }
      return EMPTY;
    })
  ))
).subscribe(data => this.pingStream.next(true));