Errors, redirects and 404s
Handle resolver errors
import { REQUEST_CONTEXT, inject } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Router, type CanActivateFn, type ResolveFn, type Route } from '@angular/router';
import { catchError, of } from 'rxjs';
import type { RenderContext } from '@fastang/core';
const previewGuard: CanActivateFn = route => route.queryParamMap.get('preview') === 'blocked'
? inject(Router).createUrlTree(['/about'])
: true;
const greeting: ResolveFn<{ message: string }> = route => {
const context = inject(REQUEST_CONTEXT) as RenderContext | null;
return inject(HttpClient).get<{ message: string }>('/api/greet/' + encodeURIComponent(route.paramMap.get('name')!)).pipe(
catchError((error: HttpErrorResponse) => {
if (context) context.status = error.status === 404 ? 404 : 502;
return of({ message: 'Greeting unavailable.' });
}),
);
};
export default {
title: 'Greeting · FastAng',
canActivate: [previewGuard],
resolve: { greeting },
runGuardsAndResolvers: 'paramsOrQueryParamsChange',
} satisfies Pick<Route, 'title' | 'canActivate' | 'resolve' | 'runGuardsAndResolvers'>;/greet/Ada?preview=blocked: SSR returns HTTP 302 to /about, a Location header and an empty body. In the browser Angular navigates to the destination. This guard is a demo: it does not implement authentication or protect an API directly.
Greeting unavailable.. During server rendering, the context sets HTTP 404 for an API 404 and HTTP 502 for other failures. In the browser, REQUEST_CONTEXT is null: client navigation cannot change the HTTP status of an already received document.
A 404 page
import { Component, REQUEST_CONTEXT, inject } from '@angular/core';
import { RouterLink } from '@angular/router';
import type { RenderContext } from '@fastang/core';
@Component({ imports: [RouterLink], template: `<h1>Page not found</h1><a routerLink="/">Back home</a>` })
export default class NotFoundPage {
constructor() { const context = inject(REQUEST_CONTEXT) as RenderContext | null; if (context) context.status = 404; }
}