...

/

Error-Handling Patterns: Rethrow and Retry Strategies

Error-Handling Patterns: Rethrow and Retry Strategies

Learn about the rethrow and retry strategies in error handling.

The rethrow strategy

A rethrow strategy consists of rethrowing the error or, in other words, propagating the error to the subscribers of the output observable of catchError. This propagation mechanism allows us to rethrow the error caught by catchError and not only handle it locally. Let’s look at this example, which is the same as the replace strategy. The only difference is in the handling error function.

Press + to interact
const { from, throwError } = require("rxjs");
const { catchError, map } = require("rxjs/operators");
const stream$ = from(["5", "10", "6", "Hello", "2"]);
stream$
.pipe(
map((value) => {
if (isNaN(value)) {
throw new Error("This is not a number");
}
return parseInt(value);
}),
catchError((error) => {
console.log("Caught Error", error);
return throwError(() => error);
})
)
.subscribe({
next: (res) => console.log("Value Emitted", res),
error: (err) => console.log("Error Occurred", err),
complete: () => console.log("Stream Completed"),
});

Note: We’ll get the error “This is not a number” whenever a non-numeric input is given.

In the handle error function, we return an observable that’s created using the throwError operator. The throwError operator creates an observable that never emits any value. Instead, it errors out immediately using the same error caught by catchError.

In other words, the output observable of catchError will also error out with the exact same error thrown by the source observable. The error can now be further handled by the rest of the observable chain if needed. Notice that the same error was logged in both the catchError block and the subscriber error handler function, as expected.

Note: In these examples, we simply log the error in the console for demonstration purposes. But in a real-world scenario, we can do much more, such as showing messages to the users.

The retry strategy

We can also retry the observable using the retry operator to give another chance to the stream. The retry operator retries an observable a specific number of times. It’s useful for retrying HTTP requests, for example.

Press + to interact
const { catchError, map, retry } = require('rxjs/operators');
const { from, throwError } = require('rxjs');
const stream$ = from(["5", "10", "6", "Hello", "2"]);
stream$
.pipe(
map((value) => {
if (isNaN(value)) {
throw new Error("This is not a number");
}
return parseInt(value);
}),
retry(2),
catchError((error) => {
console.log("Caught Error", error);
return throwError(() => error);
})
)
.subscribe({
next: (res) => console.log("Value Emitted", res),
error: (err) => console.log("Error Occurred", err),
complete: () => console.log("Stream Completed"),
});

Note: We’ll get the error “This is not a number” whenever a non-numeric input is given.

Notice that the values of the source stream were emitted two times because we gave ...