#rxjs
#tutorial
#advanced
Day 9: Error Handling & Retry Strategies
Day 9: Error Handling
In a stream, an error usually kills the subscription. We need strategies to handle this gracefully.
1. catchError
Catches an error and returns a new Observable to replace the broken one. This keeps the stream alive (or gracefully closes it).
import { of, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
const apiCall$ = throwError(() => new Error('Server limit exceeded'));
apiCall$.pipe(
catchError(err => {
console.error('Handled:', err.message);
// Return fallback value
return of('Cached Data');
})
).subscribe(val => console.log(val));
// Output: Handled: Server limit exceeded
// Output: Cached Data
2. retry
Simply resubscribes to the source observable n times if it fails.
import { interval } from 'rxjs';
import { map, retry } from 'rxjs/operators';
interval(1000).pipe(
map(val => {
if (val > 1) throw 'Boom!';
return val;
}),
retry(2) // Try 2 more times before giving up
).subscribe({
next: console.log,
error: console.error
});
3. retryWhen (Advanced)
Allows you to delay the retry. “If it fails, wait 2 seconds, then try again.”
Note: In newer RxJS, use retry({ delay: ... }).
import { timer } from 'rxjs';
import { retry } from 'rxjs/operators';
source$.pipe(
retry({
count: 3,
delay: (error, retryCount) => timer(retryCount * 1000) // Exponential backoff: 1s, 2s, 3s
})
);
4. finalize
Runs logic when the observable finishes (either complete OR error). Good for turning off loading spinners.
import { finalize } from 'rxjs/operators';
this.showSpinner = true;
data$.pipe(
finalize(() => this.showSpinner = false)
).subscribe();
Homework for Day 9:
- Create an observable that throws an error randomly (50% chance).
- Use
retry(3)to make it robust. - Use
catchErrorto return “Fallback” if it still fails after 3 tries.
Tomorrow is the Grand Finale: Building a Real-World Application!