Andrea Scarafoni
Andrea Scarafoni

Reputation: 955

How to avoid last piped ErrorObservable

I need to re-try an action for 5 times, then, if it has success, return his value, but if all 5 attempets fail, i need to throw an error.

I wrote this following, but it does not work because always end with last ErrorObservable.create ("rxjs": "5.5.6")

this.http.post<JsonResponse>(this.resourceUrl + event.body.data.id, { observe: "response" }).pipe(
  map(result => {
    if(result.data.status === "WAITING"){
      throw "WAITING";  
    }
    return result
  }) 
)
.pipe(
  retryWhen((errors) => {
    return errors
      .pipe(delay(2000))
      .pipe(take(5));
  })
)
.pipe(
  concat(
    ErrorObservable.create(
      new HttpErrorResponse({
        error: "error",
        headers: null,
        status: 500,
        statusText: "Error",
        url: "",
      })
    )
  )
);

Upvotes: 0

Views: 79

Answers (2)

Joshua McCarthy
Joshua McCarthy

Reputation: 1852

@Zerotwelve has the right idea. Though here is a solution that matches the original intent of your code.

// declare your error inside the class
static httpError = new HttpErrorResponse({
  error: "error",
  headers: null,
  status: 500,
  statusText: "Error",
  url: "",
});

this.http.post<JsonResponse>(`${this.resourceUrl}${event.body.data.id}`, { observe: "response" })
.pipe(
  tap(result => if(result.data.status === "WAITING") throw "WAITING"),
  retry(5),
  catchError(e=>of(this.httpError))
);

You can use tap() as it will always return the same value it receives, unless you throw an error.

The retry(5) operator will restart the observable should an error occur. Once it errors 5 times, then it proceeds with throwing the error.

To keep things a little cleaner, I moved your default error object to a static property. The catchError() expects you to return an observable. The of() operator will emit the parameter as an observable, which in this case is your error object.

Upvotes: 2

Zerotwelve
Zerotwelve

Reputation: 2361

this should work:

this.http.post<JsonResponse>(this.resourceUrl + event.body.data.id, { observe: "response" }).pipe(
      retry(5),
      catchError(err => this.handleError(err))
      // [...] cour code
   

Upvotes: 1

Related Questions