I wrote a function that is pipe
-able:
HandleHttpBasicError<T>()
{
return ((source:Observable<T>) => {
return source.pipe(
catchError((err:any) => {
let msg = '';
if(err && err instanceof HttpErrorResponse)
{
if(err.status == 0)
msg += "The server didn't respond";
}
throw {
err,
msg
} as CustomError
})
)
})
}
I can use this function this way in my HttpService
:
checkExist(id:string)
{
return this.http.head<void>(environment.apiUrl + 'some_url/' + id)
.pipe(
HandleHttpBasicError(),
catchError((err:CustomError) => {
if(err.msg)
throw err.msg;
if(err.err.status == HttpStatusCodes.NOT_FOUND)
throw("It doesn't exist.");
throw(err);
})
)
}
It's working great. When I subscribe to checkExist()
, I get a good error message, because HandleHttpBasicError
first catches an error and throws it to the service's catchError()
, which throwes the error message because it was not null
.
This way, it allows me to have a global catchError()
which handles error messages that will always be the same. In the future, I will do it in a HttpHandler
, but that's not the point here.
Is it ok to chain the errors with the throw
keyword?
I tried to return Observable.throwError()
, but the browser said
Observable.throwError is not a function
My imports are import {Observable, of, throwError} from 'rxjs';
.
Isn't it better to do this:
return ((source:Observable<T>) => {
return source.pipe(
catchError((err:any) => {
msg = '';
...
return of({err, msg} as CustomError)
/* instead of
throw(err)
-or-
return Observable.throwError(err) (which doesn't work)
*/
})
)
})
?
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. 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.
The catchError operator is going to take the error and pass it to the error handling function. That function is expected to return an Observable which is going to be a replacement Observable for the stream that just errored out.
Is it ok to chain the errors with the throw keyword ?
Yes, it's totally fine. rxjs try-catches such cases and converts it into an error notification.
I tryed to return Observable.throwError() but the browser say "Observable.throwError is not a function"
With rxjs6, the Observable
prototype is no longer modified to contain operators or these »creation operators«, instead they are exposed as standalone functions. You can read more about it here, but the gist of it is that you'd just return throwError(…)
, e.g.
return source$.pipe(
catchError(err => err.code === 404
? throwError("Not found")
: throwError(err)
)
)
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