So setzen Sie catchError im Timer fort (rxjs)

Aug 23 2020

Ich habe einen Dienst, der dafür verantwortlich ist, alle x Sekunden ein httpClient.get mit einem Timer auszuführen. Ich brauche diese Zeit lief zu starten , wenn der Dienst auf, so dass der Timer wird in dem definierten Service - Konstruktor . Nach meinem Verständnis sollte das Abonnement wie unten gezeigt im Timer-Bereich registriert sein (ich möchte es nicht ändern, wenn es nicht erforderlich ist, es sei denn, es ist falsch).

Das gesamte System funktioniert einwandfrei, solange keine Fehler \ Ausnahmen \ Fehler 500 Ausnahme vom Backend-Server vorliegen. Jetzt brauche ich 2 Dinge:

  1. Ich möchte Error abfangen, wenn es ein Problem im Backend-Server gibt.
  2. Ich möchte, dass der Beobachter gemäß den Timer-Zeiten (bis zum nächsten Tick) weiterläuft, auch wenn es eine Ausnahme gibt. Mein Endergebnis sollte das Erreichen des popUpAlert in der Komponente sein, wenn es eine Ausnahme gibt. Siehe meinen Code - dies ist der Webapi-Controller:
public IActionResult getSomeErrorAsTest()
{
    try
    {
        throw new Exception("Serer error");
    }
    catch(Exception ex)
    {
        return StatusCode(StatusCodes.Status500InternalServerError, new List<string>());
        //throw ex;
    }
}

Dies ist der Dienst (vorausgesetzt, die Daten ändern sich bei jeder Abrufanforderung - keine Implementierung erforderlich, wenn dies tatsächlich der Fall ist):

export class MyService
{
    MyDataSubject = new Subject<any[]>();
    MyDataChanged :Observable>any[]> = this.MyDataSubject.asObservable();
    
    subscribe :Subscription;
    constructor(private httpClient : HttpClient)
    {
        this.subscribe = timer(0, 30000).pipe(
        switchMap(()=>
            this.getData())).subscribe();
    }
    getData()
    {
        return this.httpClient.get<any[]>(<controller url>)
        .pipe(
            tap(res =>
            {
                this.MyDataSubject.next(res);
            }),
            catchError(error =>
                {
                    debugger;//I would expect to catch the debugger here, but nothing happens
                    return throwError(error);
                })
            )
    }
}   

Die Verbraucherkomponente:

export class MyComponent (private mySrv : MyService)
{
    getMyData()
    {
        let sub =this.mySrv.MyDataChanged.subscribe(result => doSomething(),
                                                    error=> popUpAlert());
    }
}

Antworten

2 RafiHenig Aug 23 2020 at 18:42

CatchErrorDer Bediener erlaubt die Behandlung von Fehlern, ändert jedoch nicht die Art der beobachtbaren Fehler. Der Fehler ist eine Endbedingung für die gegebene beobachtbare Größe, sodass die Emission stoppt. CatchErrorErmöglicht die Ausgabe des gewünschten Werts, anstatt den Fehlerrückruf ( Metasong ) des Beobachters auszulösen .

Möglicherweise möchten Sie Fehler in inner Observable (dh innen switchMap) behandeln, damit dort auftretende Fehler nicht in den Hauptstrom gelangen. Auf diese Weise wird der Hauptstrom nach dem Auftreten eines Fehlers fortgesetzt, wie unten gezeigt:

  this.subscribe = timer(0, 30000)
    .pipe(
      switchMap(() => this.getData().pipe(catchError(x => of("handle error here"))))
      // catchError(...) don't handle error here
    )
    .subscribe();