Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to propagate errors through catchError() properly?

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)
                */
            })
        )
        
    })

?

like image 706
dc-p8 Avatar asked May 11 '18 15:05

dc-p8


People also ask

How do you handle errors in observables?

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.

How do you handle errors in Mergemap?

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.

How do you throw an error in RxJS?

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.

Which RxJS operator can be chained to an observable to handle errors?

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.


1 Answers

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)
  )
)
like image 100
Ingo Bürk Avatar answered Sep 23 '22 13:09

Ingo Bürk