Angular HTTP Errors
A request can fail before or after it reaches a server. Model failure as a meaningful state and distinguish a refusal from a successful empty result.
How it works
The fixture endpoint returns a real 503 response. The component presents a bounded public message based on the status rather than displaying an arbitrary backend error body. A retry strategy needs a documented limit and should consider whether repeating the operation is safe. An automatic retry on a non-idempotent reservation request can duplicate work unless the service has an appropriate idempotency contract.
Run the code
Use a separate empty project folder with a compatible Node version: ^22.22.3, ^24.15.0 or a supported 26+ runtime. The review uses Node 24.22.1, Angular 22.2.4, CLI/build 22.2.5 and TypeScript 6.0.3. Node 22.15.1 is too old for Angular 22. Save every download at its displayed path; browsers may keep only the basename, so recreate the src folder. Run npm install, npm run build and npm start, then open the loopback address printed by the server. Run npm test for the supplied component tests. These are local teaching projects, not Bhylu publishing files.
The small loopback server serves the compiled app and fixed, read-only tool API fixtures. It is not a database, authentication or lending service. Angular examples do not run in Bhylu’s current HTML or TypeScript playground. No Apache, MySQL or PHP configuration change is needed.
Example
import { Component } from '@angular/core';
import { inject, signal } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
@Component({
selector: 'bh-http-errors',
standalone: true,
imports: [],
template: `<button type="button" (click)="load()">Load service status</button>
<p data-result>{{ message() }}</p>`,
})
export class App {
private http = inject(HttpClient);
message = signal('Not loaded');
load(): void {
this.message.set('Loading');
this.http.get('/api/failure').subscribe({
next: () => this.message.set('Unexpected success'),
error: (error: HttpErrorResponse) =>
this.message.set(
error.status === 503 ? 'Desk service unavailable' : 'Request failed',
),
});
}
}
Expected result
Not loaded
The browser and unit fixtures both reach Desk service unavailable. That message is a refusal state, not an empty catalog. Tests for real applications should also cover malformed success data, a disconnected client and a failed refresh that must not overwrite an earlier valid selection.
Supporting source
import { ApplicationConfig, provideZonelessChangeDetection } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [provideZonelessChangeDetection(), provideHttpClient()],
};