I want to throw an error from my observable's map operator based on a condition. For instance if correct API data is not received. Please see the following code:
private userAuthenticate( email: string, password: string ) { return this.httpPost(`${this.baseApiUrl}/auth?format=json&provider=login`, {userName: email, password: password}) .map( res => { if ( res.bearerToken ) { return this.saveJwt(res.bearerToken); } else { // THIS DOESN'T THROW ERROR -------------------- return Observable.throw('Valid token not returned'); } }) .catch( err => Observable.throw(this.logError(err) ) .finally( () => console.log("Authentication done.") ); }
Basically as you can see in the code, if the response (res
object) doesn't have bearerToken
I want to throw out an error. So that in my subscription it goes into the 2nd parameter (handleError
) mentioned below.
.subscribe(success, handleError)
Any suggestions?
Catch errors in the observable stream Another option to catch errors is to use the CatchError Operator. The CatchError Operators catches the error in the observable stream as and when the error happens. This allows us to retry the failed observable or use a replacement observable.
You'll need to use retry or retryWhen (names are pretty self-explanatory) — these operators will retry a failed subscription (resubscribe to the source observable, once an error is emitted.
Just throw the error inside the map()
operator. All callbacks in RxJS are wrapped with try-catch blocks so it'll be caught and then sent as an error
notification.
This means you don't return anything and just throw the error:
map(res => { if (res.bearerToken) { return this.saveJwt(res.bearerToken); } else { throw new Error('Valid token not returned'); } })
The throwError()
(former Observable.throw()
in RxJS 5) is an Observable that just sends an error
notification but map()
doesn't care what you return. Even if you return an Observable from map()
it'll be passed as next
notification.
Last thing, you probably don't need to use .catchError()
(former catch()
in RxJS 5). If you need to perform any side effects when an error happens it's better to use tap(null, err => console.log(err))
(former do()
in RxJS 5) for example.
Jan 2019: Updated for RxJS 6
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With