Peter Morris
Peter Morris

Reputation: 23234

Why is rxjs not passing my Observable.throw to subscribers?

I have the following code in a service which creates an observable from a Http request.

  const httpObservable = this.http.post(url, JSON.stringify(request))
    .map((res: Response) => res.json())
    .catch((error, caught) => {
      console.log('There was an API error for ' + url);
      console.log('Rethrowing');
      return Observable.throw(error);
    });
  return httpObservable;

There is no server available at the specified url and the catch block is being executed. As you can see the catch handler returns an Observable.throw(error) which should (as far as I understand) be caught in the next block that uses the above function.

const request = new Api.ThemeInfoGetQuery();
console.log('Sending request');
this.response = this.apiService.request(Api.ThemeInfoGetQuery.url, request);
console.log('Setting catch');
this.response.catch((err: any, caught: Observable<Api.ThemeInfoGetResponse>) => {
  console.log('The rethrown error was detected');
  return Observable.throw(err);
});
this.response.subscribe(x => {
  console.log('There was no error');
});

This is the output I expect to see in the console.

  1. Sending request
  2. Setting catch
  3. There was an API error
  4. Rethrowing
  5. The rethrown error was detected

But I am only seeing up to step 4. Can anyone suggest what I might try to ensure the subscriber's .catch is also executed?

Sending request
load-theme.resolver.ts:31 Setting catch
zone.js:2177 OPTIONS http://localhost:5000/api/theme/get-theme net::ERR_CONNECTION_REFUSED
scheduleTask @ zone.js:2177
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:384
onScheduleTask @ zone.js:274
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:378
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:209
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.scheduleMacroTask @ zone.js:232
(anonymous) @ zone.js:2201
send @ VM5471:3
(anonymous) @ http.es5.js?9c1c:1275
webpackJsonp.../../../../rxjs/Observable.js.Observable._trySubscribe @ Observable.js:171
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:159
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/do.js.DoOperator.call @ do.js?d062:63
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/delay.js.DelayOperator.call @ delay.js?1cee:63
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/catch.js.CatchOperator.call @ catch.js?0239:79
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/finally.js.FinallyOperator.call @ finally.js?667f:26
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../../src/app/tru-control/resolvers/load-theme.resolver.ts.LoadThemeResolver.resolveBrand @ load-theme.resolver.ts:37
LoadThemeResolver @ load-theme.resolver.ts:19
_createClass @ core.es5.js:9518
_createProviderInstance$1 @ core.es5.js:9486
resolveNgModuleDep @ core.es5.js:9471
webpackJsonp.../../../core/@angular/core.es5.js.NgModuleRef_.get @ core.es5.js:10557
webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.getToken @ router.es5.js?1fca:4566
webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.getResolver @ router.es5.js?1fca:4554
webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.resolveNode @ router.es5.js?1fca:4534
webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.runResolve @ router.es5.js?1fca:4515
(anonymous) @ router.es5.js?1fca:4282
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js?a3bf:120
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js?a3bf:110
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/observable/ArrayObservable.js.ArrayObservable._subscribe @ ArrayObservable.js:114
webpackJsonp.../../../../rxjs/Observable.js.Observable._trySubscribe @ Observable.js:171
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:159
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js?a3bf:85
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/reduce.js.ReduceOperator.call @ reduce.js?4c7d:74
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
subscribeToResult @ subscribeToResult.js:22
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._innerSub @ mergeMap.js?a3bf:130
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js?a3bf:127
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js?a3bf:110
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber.notifyNext @ mergeMap.js?a3bf:143
webpackJsonp.../../../../rxjs/InnerSubscriber.js.InnerSubscriber._next @ InnerSubscriber.js:23
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next @ map.js:83
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber.notifyNext @ mergeMap.js?a3bf:143
webpackJsonp.../../../../rxjs/InnerSubscriber.js.InnerSubscriber._next @ InnerSubscriber.js:23
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/every.js.EverySubscriber.notifyComplete @ every.js?5a03:53
webpackJsonp.../../../../rxjs/operator/every.js.EverySubscriber._complete @ every.js?5a03:70
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.complete @ Subscriber.js:114
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._complete @ mergeMap.js?a3bf:135
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.complete @ Subscriber.js:114
webpackJsonp.../../../../rxjs/observable/ArrayObservable.js.ArrayObservable._subscribe @ ArrayObservable.js:116
webpackJsonp.../../../../rxjs/Observable.js.Observable._trySubscribe @ Observable.js:171
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:159
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js?a3bf:85
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/every.js.EveryOperator.call @ every.js?5a03:33
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
subscribeToResult @ subscribeToResult.js:22
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._innerSub @ mergeMap.js?a3bf:130
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js?a3bf:127
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js?a3bf:110
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/every.js.EverySubscriber.notifyComplete @ every.js?5a03:53
webpackJsonp.../../../../rxjs/operator/every.js.EverySubscriber._complete @ every.js?5a03:70
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.complete @ Subscriber.js:114
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._complete @ mergeMap.js?a3bf:135
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.complete @ Subscriber.js:114
webpackJsonp.../../../../rxjs/observable/ArrayObservable.js.ArrayObservable._subscribe @ ArrayObservable.js:116
webpackJsonp.../../../../rxjs/Observable.js.Observable._trySubscribe @ Observable.js:171
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:159
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js?a3bf:85
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/every.js.EveryOperator.call @ every.js?5a03:33
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js?a3bf:85
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
subscribeToResult @ subscribeToResult.js:22
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._innerSub @ mergeMap.js?a3bf:130
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js?a3bf:127
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js?a3bf:110
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next @ map.js:83
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber.notifyNext @ mergeMap.js?a3bf:143
webpackJsonp.../../../../rxjs/InnerSubscriber.js.InnerSubscriber._next @ InnerSubscriber.js:23
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next @ map.js:83
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/observable/ScalarObservable.js.ScalarObservable._subscribe @ ScalarObservable.js:49
webpackJsonp.../../../../rxjs/Observable.js.Observable._trySubscribe @ Observable.js:171
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:159
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
subscribeToResult @ subscribeToResult.js:22
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._innerSub @ mergeMap.js?a3bf:130
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js?a3bf:127
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js?a3bf:110
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber.notifyNext @ mergeMap.js?a3bf:143
webpackJsonp.../../../../rxjs/InnerSubscriber.js.InnerSubscriber._next @ InnerSubscriber.js:23
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next @ map.js:83
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/observable/ScalarObservable.js.ScalarObservable._subscribe @ ScalarObservable.js:49
webpackJsonp.../../../../rxjs/Observable.js.Observable._trySubscribe @ Observable.js:171
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:159
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
subscribeToResult @ subscribeToResult.js:22
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._innerSub @ mergeMap.js?a3bf:130
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js?a3bf:127
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js?a3bf:110
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber._next @ Subscriber.js:125
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next @ map.js:83
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next @ map.js:83
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next @ map.js:83
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:89
webpackJsonp.../../../../rxjs/operator/last.js.LastSubscriber._complete @ last.js?576b:110
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.complete @ Subscriber.js:114
webpackJsonp.../../../../rxjs/operator/mergeAll.js.MergeAllSubscriber._complete @ mergeAll.js:94
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.complete @ Subscriber.js:114
webpackJsonp.../../../../rxjs/observable/ScalarObservable.js.ScalarObservable._subscribe @ ScalarObservable.js:51
webpackJsonp.../../../../rxjs/Observable.js.Observable._trySubscribe @ Observable.js:171
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:159
webpackJsonp.../../../../rxjs/operator/mergeAll.js.MergeAllOperator.call @ mergeAll.js:63
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/last.js.LastOperator.call @ last.js?576b:39
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/catch.js.CatchOperator.call @ catch.js?0239:79
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js?a3bf:85
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js?a3bf:85
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js?a3bf:85
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js?a3bf:85
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapOperator.call @ mergeMap.js?a3bf:85
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
webpackJsonp.../../../../rxjs/operator/map.js.MapOperator.call @ map.js:54
webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe @ Observable.js:156
(anonymous) @ Observable.js:203
ZoneAwarePromise @ zone.js:776
webpackJsonp.../../../../rxjs/Observable.js.Observable.forEach @ Observable.js:199
(anonymous) @ router.es5.js?1fca:4148
ZoneAwarePromise @ zone.js:776
webpackJsonp.../../../router/@angular/router.es5.js.Router.runNavigate @ router.es5.js?1fca:4073
(anonymous) @ router.es5.js?1fca:4040
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:365
onInvoke @ core.es5.js:3890
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:364
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run @ zone.js:125
(anonymous) @ zone.js:760
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:398
onInvokeTask @ core.es5.js:3881
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:397
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask @ zone.js:165
drainMicroTaskQueue @ zone.js:593
api.service.ts?c446:92 There was an API error for http://localhost:5000/api/theme/get-theme
api.service.ts?c446:100 Rethrowing
core.es5.js:1020 ERROR Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers…}headers: Headersok: falsestatus: 0statusText: ""type: 3url: null_body: ProgressEventbubbles: falsecancelBubble: falsecancelable: falsecomposed: falsecurrentTarget: XMLHttpRequestdefaultPrevented: falseeventPhase: 0isTrusted: truelengthComputable: falseloaded: 0path: Array(0)returnValue: truesrcElement: XMLHttpRequesttarget: XMLHttpRequesttimeStamp: 5433.305total: 0type: "error"__proto__: ProgressEvent__proto__: Body

Upvotes: 3

Views: 472

Answers (3)

0mpurdy
0mpurdy

Reputation: 3353

You can throw a new error within the catch:

.catch(err => {
    this.error = "Error: " + err.status
    throw new Error('Got a 404')
})

and this will pass it on down the stream which can then be caught again:

.subscribe(
  result => console.log(result),
  err => {
    console.log('subscribe error')
  });

Live plunker example

You can also do it with Observable.throw() similar to how you have in your question

.catch(err => {
  console.log('Error: ', err)
  return Observable.throw('new error')
})
.subscribe(
  result => console.log(result));

As @cartant mentioned in his answer: You are not using the observable that is returned, another option instead of assigning the response to the result of the .catch is to subscribe directly to the result as shown above.

Updated plunker with both methods.

Upvotes: 0

cartant
cartant

Reputation: 58400

catch is an RxJS operator and as such it returns an observable - which you are ignoring. It's the returned observable that has the catch applied, not the observable upon which catch is called.

For your catch to have an effect, you'd need to use the returned observable, like this:

this.response = this.response.catch((err, caught) => {
  console.log('The rethrown error was detected');
  return Observable.throw(err);
});

Upvotes: 1

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657308

this.response.subscribe(
  x => {
    console.log('There was no error');
  }
  err => {
    console.log('There was error', err);
  }
);

Upvotes: 0

Related Questions