Resilience in Communication: HTTP Error Handling in Angular
Master the art of handling HTTP failures in Angular to build robust, user-friendly applications that never crash unexpectedly.
/* An HTTP request is sent... */
The Unstable Request
In a perfect world, every HTTP request gets a successful response. In reality, networks fail, servers crash, and requests are invalid. An unhandled error can crash your application, leading to a poor user experience. Robust applications must anticipate and manage these failures gracefully.
Intercepting with `catchError`
Angular's HttpClient
returns an RxJS Observable
. We can use the .pipe()
method on this observable to chain operators. The most important for error handling is catchError
, which intercepts an error, allowing you to process it without crashing the stream.
Diagnosing with `HttpErrorResponse`
The error caught by catchError
is an HttpErrorResponse
object. This object contains vital information. You can check error.status
(e.g., 404, 500) to understand the failure type and distinguish between a client-side network error and a server-side API error.
Propagating with `throwError`
After logging or handling an error, you should usually re-throw it using the RxJS throwError
function. This ensures that the component subscribing to the service knows the request failed and can update the UI accordingly (e.g., by showing an error message instead of a loading spinner).
Practice Zone
Interactive Test 1: Match the Operators
Drag the RxJS function to its correct description.
Arrastra en el orden correspondiente.
Arrastra las opciones:
Completa el código:
Interactive Test 2: Build the Handler
Rellena los huecos en cada casilla.
import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { throwError, Observable } from 'rxjs'; import { } from 'rxjs/operators'; // ... service definition getData(): Observable<any> { return this.http.get('/api/data').pipe( (this.handleError) ); } private handleError(error: HttpErrorResponse) { // Logic to handle client or server error return ('Something went wrong.'); }
Practice Example: Code Editor
In a service, create a method that fetches data from a fake API endpoint (`/api/users`) and includes full `catchError` and `throwError` logic.
Advanced Error Handling Patterns
Beyond a single service, Angular provides powerful, application-wide patterns for managing HTTP errors efficiently.
1. Centralized Handling with HttpInterceptor
An HttpInterceptor
allows you to intercept *every* single HTTP request and response. This is the perfect place to put centralized error handling logic, so you don't have to repeat it in every service.
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
// Global error logic here
return throwError(() => error);
})
);
}
}
2. Automatic Retries with the `retry` Operator
For temporary network issues or transient server errors (like a 503), you can automatically retry a failed request. The retry
operator can be added to the pipe before catchError
.
// In a service method
return this.http.get('/api/data').pipe(
retry(2), // Retries up to 2 times
catchError(this.handleError)
);
3. Showing User-Friendly Messages
In your component, the `error` callback of the `subscribe` method is where you handle the UI. You can set a property to display an error message to the user, providing a much better experience than a broken page.
this.dataService.getData().subscribe({
next: (data) => { /* ... */ },
error: (err) => { this.errorMessage = 'Could not load data.'; }
});
Practical Takeaway: Combining service-level handlers, global interceptors, and component-level UI feedback creates a truly resilient and professional Angular application.
Angular HTTP Glossary
- HttpClient
- Angular's built-in service for making HTTP requests. It returns Observables from the RxJS library.
- Observable
- A stream of data that can be subscribed to. HTTP requests produce an observable that emits a single value (the response) or an error.
- pipe()
- A method on Observables that allows you to chain together multiple RxJS operators to process the data in the stream.
- catchError
- An RxJS operator used inside
.pipe()
to intercept any errors that occur in the observable stream. - HttpErrorResponse
- An object passed to the
catchError
handler that contains detailed information about a failed HTTP request, including the status code and error body. - throwError
- An RxJS function that creates a new observable that immediately emits an error. It's used to propagate an error down the stream to the subscriber.