Vyhledávání na webu

typescript - Jak zachytit chybu ve dvou různých bodech v RxJS/Angular?


Předpokládejme tento úryvek Angular 2:

export class ApiService {
  // do stuff
  request(...): Observable<Response> {
    return this.http.request(...)
      .share()
      .catch((error: any) => {
        let errMsg = 'my error';
        // do more stuff...
        // tried: throw errMsg;
        // tried: return Observable.throw(errMsg);
      });
  }
}

Pak :

api.request(...).catch(() => {
  console.log('caught');
  return Observable.from([]);
}).subscribe({
  console.log('everything fine');
});

Callback next, který je předán do subscribe, se zavolá bez problémů, když požadavek uspěje, ale callback předaný do catch se nezavolá.

Snažil jsem se řešit chybu ve dvou různých částech kódu, které mají odlišné odpovědnosti. Chtěl bych, aby se chybová zpráva vyvolaná v ApiService.request dostala do druhého callbacku, abych mohl dále zpřesnit svou odpověď uživateli. Zkoušel jsem jak throw errMsg, tak návrat Observable.throw(errMsg).

Důvod, proč používám .share() pro observable, je ten, že nechci, aby http klient generoval jeden požadavek na každého odběratele.

Kde dělám tuto chybu?

UPRAVIT:

Můj výše uvedený příklad ve skutečnosti nezachytil problém, který jsem měl. Tento druhý úryvek umožňuje jeho reprodukci:

const a = Rx.Observable.create(function(observer){
  observer.error('h');
}).share().catch(err=> {
  console.error('first place',err);
  throw 'err'
})
.subscribe(() => null)
.subscribe(console.log, console.error);

První odběr selhával při zachycení chyby (protože nebyl definován žádný zpracovatel chyb) a přerušoval řetězec k druhému odběrateli.

Odpověď č. 1

Z toho, co jsem pochopil, chcete zachytit chybu na dvou místech. Podle dokumentace je potřeba použít throw. Zkoušel jsem to a u mě to funguje dobře. Tady je ukázka kódu:

const a = Rx.Observable.create(function(observer){
    observer.error('h');
});

a.catch(err=> {
   console.error('first place',err);
   throw 'err'
}).subscribe(console.log,console.error);

Výstup

x first place 
x err 

JSBin : https://jsbin.com/jefalazibo/edit?html,js,console

V kódu komponenty nemusíte psát další catch. subscribe bere tři funkce jako argumenty

 subscribe(onSuccess, onError, onComplete);

Dokumentace: https://github.com/ReactiveX/rxjs/blob/master/src/operator/catch.ts (zkontrolujte příklad 3)