Get your own Angular server
main.ts
index.html
 
import { bootstrapApplication } from '@angular/platform-browser';
import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { provideHttpClient, HttpClient, withInterceptors, HttpResponse, HttpErrorResponse, HttpRequest, HttpHandlerFn } from '@angular/common/http';
import { of, throwError } from 'rxjs';

// Fake HTTP interceptor so the demo works without external network calls
function mockHttp(req: HttpRequest<any>, next: HttpHandlerFn) {
  if (req.method === 'GET' && req.url.includes('jsonplaceholder.typicode.com/usersx')) {
    return throwError(() => new HttpErrorResponse({ status: 404, statusText: 'Not Found', url: req.url }));
  }
  if (req.method === 'GET' && req.url.includes('jsonplaceholder.typicode.com/users')) {
    const body = [
      { id: 1, name: 'Leanne Graham', email: 'leanne@example.com' },
      { id: 2, name: 'Ervin Howell', email: 'ervin@example.com' }
    ];
    return of(new HttpResponse({ status: 200, body }));
  }
  return next(req);
}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  styles: [`
    button { margin-right: 8px; }
    .error { color: crimson; }
    .ok { color: seagreen; }
  `],
  template: `
    <h3>HTTP Error Handling</h3>

    <div>
      <button (click)="loadOk()" [disabled]="loading">Load OK</button>
      <button (click)="loadFail()" [disabled]="loading">Load Fail</button>
      <button (click)="retry()" [disabled]="!lastAction || loading">Retry</button>
    </div>

    <p *ngIf="loading">Loading...</p>
    <p *ngIf="error" class="error">{{ error }}</p>
    <p *ngIf="!error && data" class="ok">Loaded {{ isArray(data) ? data.length + ' items' : '1 item' }}</p>

    <ul *ngIf="isArray(data)">
      <li *ngFor="let u of data">{{ u.name }} ({{ u.email }})</li>
    </ul>
  `
})
export class App {
  http = inject(HttpClient);
  loading = false;
  error = '';
  data: any[] | null = null;
  lastAction = '';
  isArray(value: unknown): value is any[] { return Array.isArray(value as any); }

  fetch(url: string): void {
    this.loading = true;
    this.error = '';
    this.data = null;
    this.http.get<any[]>(url).subscribe({
      next: (res) => { this.data = res; this.loading = false; },
      error: (err) => {
        const status = err?.status ?? 'unknown';
        this.error = `Request failed (status ${status}). Please try again.`;
        this.loading = false;
      }
    });
  }

  loadOk() {
    this.lastAction = 'ok';
    this.fetch('https://jsonplaceholder.typicode.com/users');
  }

  loadFail() {
    this.lastAction = 'fail';
    this.fetch('https://jsonplaceholder.typicode.com/usersx');
  }

  retry() {
    if (this.lastAction === 'ok') this.loadOk();
    else if (this.lastAction === 'fail') this.loadFail();
  }
}

bootstrapApplication(App, { providers: [provideHttpClient(withInterceptors([mockHttp]))] });

                    
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Angular HTTP Error Handling</title>
</head>
<body>
  <app-root></app-root>
</body>
</html>