Reputation: 5684
I have the following code I'm using in my Angular (4.0) application during $http calls.
return this.httpComponent.post(serviceUrl, request, args)
.map((res: any) => res.json() as R)
.catch((error: any) => Observable.throw(error.json().error || error.json().errorMessage || 'Server error'));
After testing this I realized multiple subscriptions were triggering the request multiple times. Thanks to this post: Angular2 http.post gets executed twice I found out I needed to share() the result.
This works to get rid of the multiple calls but now it seems my catch() method isn't being hit. I want my catch() to throw the error.
I tried the two options below but they did not work:
return this.httpComponent.post(serviceUrl, request, args)
.map((res: any) => res.json() as R)
.share()
.catch((error: any) => Observable.throw(error.json().error || error.json().errorMessage || 'Server error'));
return this.httpComponent.post(serviceUrl, request, args)
.map((res: any) => res.json() as R)
.catch((error: any) => Observable.throw(error.json().error || error.json().errorMessage || 'Server error')
.share()); //This doesn't make sense since my catch() isn't returning an Observable
Anyone know how I can share() and catch(throw...) at the same time?
Upvotes: 1
Views: 763
Reputation: 58400
The second option you've included in your question attaches the catch
to the Observable.throw
. If that is corrected, you should see the behaviour you are expecting:
const source = Rx.Observable
.interval(500)
.map((value) => {
if (value === 2) {
throw new Error("Boom!");
}
console.log(`value: ${value}`)
return value;
})
.catch((error) => Rx.Observable.throw(new Error(`Re-thrown ${error.message}`)))
.share();
source.subscribe(
(value) => console.log(`subscription 1: ${value}`),
(error) => console.log(`subscription 1: ${error}`)
);
source.subscribe(
(value) => console.log(`subscription 2: ${value}`),
(error) => console.log(`subscription 2: ${error}`)
);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script>
Upvotes: 0
Reputation: 5684
As mentioned in my comment to @cartant 's answer, if any subscriber doesn't have an error handler (ie: doesn't care about any error scenarios) an exception is thrown and all subsequent subscribers are never informed of the original error.
This seems like a design flaw in my opinion. Here is the example (Copied from @cartant 's answer)
const source = Rx.Observable
.interval(500)
.map((value) => {
if (value === 2) {
throw new Error("Boom!");
}
console.log(`value: ${value}`)
return value;
})
.catch((error) => Rx.Observable.throw(new Error(`Re-thrown ${error.message}`)))
.share();
source.subscribe(
(value) => console.log(`subscription 1: ${value}`)
);
source.subscribe(
(value) => console.log(`subscription 2: ${value}`),
(error) => console.log(`subscription 2: ${error}`)
);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
Upvotes: 2