4

currently I have my code structured like this, and it is working great:

// service:
getRequestA() { return this.http.get(someUrl) }
getRequestB(id) { return this.http.get(someUrl + id) }
getRequestC(id) { return this.http.get(someUrl + id) }
getAll() {
  return getRequestA()
    .pipe(
      mergeMap((resp) => {
        return this.getRequestB(resp.id)
      }),
      mergeMap((resp) => {
        return this.getRequestC(resp.id)
      })
    )
}

which allows me to do this in my component:

// component:
service.getAll().subscribe(resp => {
  // result of service.getRequestC()
}, error => {
  // error occurred in any 1 of the 3 http calls
});

This is great as I need the result of each call before firing off the next, and I only care about the final result. However, now I have a desire to know which specifically of the 3 http calls failed, to display a better error to the user. I've tried a bunch of stuff but can't figure out to throw custom errors in the service that I could then differentiate between in the component. Thanks in advance for any suggestions!

1 Answer 1

6

An arrangement like this should let you tag and re-throw any errors:

const tagError = (tag, error) => {
  error.tag = tag;
  return error;
};

getAll() {
  return getRequestA().pipe(
    catchError(error => { throw tagError("A", error); }),
    mergeMap(resp => this.getRequestB(resp.id).pipe(
      catchError(error => { throw tagError("B", error); })
    )),
    mergeMap(resp => this.getRequestC(resp.id).pipe(
      catchError(error => { throw tagError("C", error); })
    ))
  );
}

In fact, you could take this further and turn the tagError function into a pipeable operator:

const tagError = tag => catchError(error => {
  error.tag = tag;
  throw error;
});

getAll() {
  return getRequestA().pipe(
    tagError("A"),
    mergeMap(resp => this.getRequestB(resp.id).pipe(tagError("B"))),
    mergeMap(resp => this.getRequestC(resp.id).pipe(tagError("C")))
  );
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.