Skip to content
advanced Phase 10 · RxJS Operators for Angular

Error Handling and Retry Patterns

Keep streams alive when a source fails transiently.

40m
0 problems
Topic Progress 0%

Retry and Error Recovery

RxJS provides operators to handle errors and keep streams alive when sources fail transiently.

retry — Resubscribe on Error

import { retry } from 'rxjs/operators';

this.http.get<User[]>('/api/users').pipe(
  retry(3) // Resubscribe up to 3 times on error
).subscribe();

retryWith — Custom Retry Strategy

import { retry, timer } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

this.http.get<User[]>('/api/users').pipe(
  retry({
    count: 3,
    delay: (error, retryCount) => {
      console.log(`Retry ${retryCount} after error:`, error.message);
      return timer(1000 * retryCount); // Exponential backoff
    },
  })
).subscribe();

catchError — Recover with Fallback

import { catchError, of } from 'rxjs';

this.http.get<User[]>('/api/users').pipe(
  catchError(error => {
    console.error('Failed to load users:', error);
    return of([]); // Return empty array as fallback
  })
).subscribe(users => {
  this.users = users;
});

catchError — Re-throw

import { catchError, throwError } from 'rxjs';

this.http.get<User[]>('/api/users').pipe(
  catchError(error => {
    return throwError(() => new Error('Custom error message'));
  })
).subscribe();

Throttling and Debouncing

Throttling operators control the rate of emissions, preventing excessive work from noisy streams.

debounceTime — Wait for Silence

import { debounceTime } from 'rxjs/operators';

this.searchInput.valueChanges.pipe(
  debounceTime(300) // Wait 300ms after last emission
).subscribe(query => {
  this.search(query);
});

throttleTime — Limit Rate

import { throttleTime } from 'rxjs/operators';

this.scroll$.pipe(
  throttleTime(200) // Emit at most once per 200ms
).subscribe(() => {
  this.updateScrollPosition();
});

delay — Shift Emissions

import { delay } from 'rxjs/operators';

this.data$.pipe(
  delay(1000) // Delay all emissions by 1 second
).subscribe();

Throttling Operator Comparison

Operator Behavior Use When
debounceTime Wait for silence Search inputs
throttleTime Limit rate Scroll, resize events
auditTime Emit last in window Button clicks
sampleTime Emit latest on interval Polling
delay Shift all emissions Timed sequences

Practical Example: Search with Debounce

@Component({
  selector: 'app-search',
  template: `
    <input [formControl]="searchControl" placeholder="Search...">
    <p *ngFor="let result of results">{{ result.name }}</p>
  `,
})
export class SearchComponent implements OnInit {
  searchControl = new FormControl('');
  results: SearchResult[] = [];

  ngOnInit(): void {
    this.searchControl.valueChanges.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      switchMap(query => this.searchService.search(query)),
      catchError(() => of([]))
    ).subscribe(results => {
      this.results = results;
    });
  }
}

Exponential Backoff Pattern

this.http.get('/api/data').pipe(
  retry({
    count: 3,
    delay: (error, retryCount) => timer(1000 * Math.pow(2, retryCount)),
    // 2s, 4s, 8s
  }),
  catchError(() => of(fallbackData))
).subscribe();

Quiz

1. What does the retry operator do?

Question 1 options

2. What does catchError do?

Question 2 options

3. Which operator should you use for search input throttling?

Question 3 options

Flashcards

Question

What does retry do?

Answer

Resubscribes to the source on error. Gives transient failures a second chance.

Question

What does catchError do?

Answer

Intercepts errors, allows fallback values or re-throwing.

Question

Which operator for search throttling?

Answer

debounceTime — waits for silence before emitting.

Revision Notes

Key Takeaways

  • 1. retry resubscribes on error
  • 2. catchError intercepts and recovers from errors
  • 3. debounceTime throttles noisy streams
  • 4. Exponential backoff prevents thundering herd

Interview Tips

  • • Explain retry vs catchError
  • • Be ready to describe throttling operators
  • • Mention exponential backoff for production resilience

Cheat Sheet

Error Handling and Retry Cheat Sheet

retry:

retry(3) // Resubscribe up to 3 times

catchError:

catchError(() => of(fallbackValue))

debounceTime:

debounceTime(300) // Wait 300ms after last emission

Exponential backoff:

retry({ count: 3, delay: (err, i) => timer(1000 * Math.pow(2, i)) })

Continue Learning