RxJs: How to handle errors in infinitely emitting observable


Lets say i have a button which sends an api request to external server when clicked. The api requests may fail occasionally, we would want the observable to keep running even though a failure has occurred on the pipeline.





lets use this example





import {
fromEvent,
scan,
map,
of,
catchError,
EMPTY
} from 'rxjs';

let i = 0;

fromEvent(document, 'click').pipe(map(() => {
i += 1;
if (i % 2 === 0) {
throw new Error('an error occured')
}
return i;
}), catchError(() => EMPTY)).subscribe({
next: (count) => console.log('Clicked ' + count + ' times'),
error: (error) => console.log('error occured'),
complete: () => console.log('completed')
});





This will print this output upon click






Clicked 1 times





completed






As you can see if we catch an error and return EMPTY observable the subscriber completes. i want to prevent this from happening, i want it to listen to infinite click events and it should not complete.





introducing retry method ..





By definition it does the following






Returns an Observable that mirrors the source Observable with the exception of an error.


https://rxjs.dev/api/index/function/retry




so when an error occurs we just call retry() with no arguments. It is important to note that using the retry operator with no arguments can cause the observable to retry indefinitely, which can be problematic if the error is not recoverable. In such cases, it is generally better to use the catchError operator to handle the error and continue the sequence with a new observable, or to use the retry operator with a finite number of retries.





import {
fromEvent,
retry,
map,
} from 'rxjs';

let i = 0;

fromEvent(document, 'click').pipe(map(() => {
i += 1;
if (i % 2 === 0) {
console.log('error occured for click count: ' + i)
throw new Error('an error occured')
}
return i;
}), retry()).subscribe({
next: (count) => console.log('Clicked ' + count + ' times'),
error: (error) => console.log('error occured'),
complete: () => console.log('completed')
});





This subscriber will continue listening to click events even when error occurs, here is an example output from this setup





Clicked 1 times
error occured for click count: 2
Clicked 3 times
error occured for click count: 4
Clicked 5 times
error occured for click count: 6
Clicked 7 times
error occured for click count: 8
Clicked 9 times
error occured for click count: 10
Clicked 11 times
error occured for click count: 12

Share:

0 comments:

Post a Comment