From e2050759a43ff033f172b52ae0f98f3ce21d6481 Mon Sep 17 00:00:00 2001 From: Matthieu Riegler Date: Mon, 31 Aug 2026 19:48:44 +0200 Subject: [PATCH] docs: add error boundaries entries --- .../app/routing/navigation-entries/index.ts | 6 ++ .../components/programmatic-rendering.md | 15 ++++ .../guide/templates/error-boundaries.md | 86 +++++++++++++++++++ pnpm-lock.yaml | 19 ++++ tools/manual_api_docs/blocks/boundary.md | 32 +++++++ 5 files changed, 158 insertions(+) create mode 100644 adev/src/content/guide/templates/error-boundaries.md create mode 100644 tools/manual_api_docs/blocks/boundary.md diff --git a/adev/src/app/routing/navigation-entries/index.ts b/adev/src/app/routing/navigation-entries/index.ts index 424dc3a9f29..1465f2d56ee 100644 --- a/adev/src/app/routing/navigation-entries/index.ts +++ b/adev/src/app/routing/navigation-entries/index.ts @@ -263,6 +263,12 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'guide/templates/defer', contentPath: 'guide/templates/defer', }, + { + label: 'Error boundaries with @boundary', + path: 'guide/templates/error-boundaries', + contentPath: 'guide/templates/error-boundaries', + status: 'new', + }, { label: 'Expression syntax', path: 'guide/templates/expression-syntax', diff --git a/adev/src/content/guide/components/programmatic-rendering.md b/adev/src/content/guide/components/programmatic-rendering.md index 39929912ee1..d439857bbb7 100644 --- a/adev/src/content/guide/components/programmatic-rendering.md +++ b/adev/src/content/guide/components/programmatic-rendering.md @@ -396,3 +396,18 @@ export class PopupService { } } ``` + +## Handling rendering errors + +When dynamically creating components using `ViewContainerRef.createComponent` or the standalone `createComponent` function, you can provide an `onError` callback in the options object to handle errors that occur during the rendering or change detection phases. This is the programmatic equivalent of using an `@error` block in templates. + +```ts +viewContainerRef.createComponent(DynamicComponent, { + onError: (err: Error, details: ErrorDetails) => { + console.error('Component rendering failed:', err); + // Render an alternative UI or log metrics + }, +}); +``` + +NOTE: The `onError` callback only catches errors that occur during the rendering or change detection phases. It does not catch errors that occur during component instantiation (for example, in the constructor). Angular throws construction errors synchronously when you call the API. diff --git a/adev/src/content/guide/templates/error-boundaries.md b/adev/src/content/guide/templates/error-boundaries.md new file mode 100644 index 00000000000..a3466aff366 --- /dev/null +++ b/adev/src/content/guide/templates/error-boundaries.md @@ -0,0 +1,86 @@ +# Error boundaries with `@boundary` + +IMPORTANT: `@boundary` is in [developer preview](reference/releases#developer-preview). + +Angular templates support error boundaries to gracefully handle runtime errors that occur during rendering and change detection. + +Error boundaries prevent a single component's failure from crashing the entire application and provide a way to display fallback UI to the user. + +## Catching errors with `@boundary` and `@error` + +The `@boundary` block wraps a section of your template. If any component or directive inside this boundary throws an error during initialization or change detection, the framework catches the error and renders the `@error` block instead. + +```angular-html +@boundary { + +} @error { +

Something went wrong!

+} +``` + +## Accessing the error object + +You can access the caught error by accessing the implicit `$error` variable: + +```angular-html +@boundary { + +} @error { +

Error occurred: {{ $error.message }}

+} +``` + +## Resetting the boundary + +You can attempt to re-render the content of the `@boundary` by calling the implicit `$reset` function in the `@error` block. When called, it resets the boundary state and tries to render the original content again. + +```angular-html +@boundary { + +} @error { +

Loading failed.

+ +} +``` + +## Conditional error handling with `when` + +You can use `when` clauses to conditionally handle specific types of errors, allowing you to provide different fallback UIs. Angular evaluates this condition when it catches an error. + +```angular-html +@boundary { + +} @error (let err; reset = $reset; when isRenderError(err)) { +

Network issue. Check your connection.

+ +} @error { +

An unexpected error occurred: {{ $error.message }}

+} +``` + +Order your `@error` blocks from most specific to least specific, as Angular evaluates the `when` clauses in order and uses the first one that evaluates to true. A final `@error` block without a `when` clause acts as a catch-all fallback. + +## Global error handler integration + +When a boundary catches an error, Angular can still notify the global `ErrorHandler`. You can implement the optional `onViewError` hook in your custom `ErrorHandler` to log these caught errors to your error tracking service. + +```ts +@Injectable() +export class MyErrorHandler implements ErrorHandler { + handleError(error: any): void { + // Handle uncaught errors + } + + onViewError(error: Error, details: ErrorDetails): void { + // Handle errors caught by a @boundary + console.warn('Caught by boundary:', details.boundary); + myErrorTrackingService.log(error); + } +} +``` + +IMPORTANT: If an `@error` block itself throws an error, the error propagates to the next outer `@boundary` or Angular treats it as an unhandled application error. + +## Dynamic views and programmatic error handling + +Error handling isn't limited to template syntax. If you are creating components or embedded views dynamically, you can use the `onError` option to handle errors. See the [Handling rendering errors](guide/components/programmatic-rendering#handling-rendering-errors) section in the programmatic rendering guide for more information. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 629bf946ef8..965de17daa4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,9 @@ importers: .: configDependencies: {} packageManagerDependencies: + '@pnpm/exe': + specifier: 12.3.4 + version: 12.3.4 pnpm: specifier: 12.3.4 version: 12.3.4 @@ -56,6 +59,11 @@ packages: cpu: [x64] os: [win32] + '@pnpm/exe@12.3.4': + resolution: {integrity: sha512-Rq7JokWAyYF9IFfn8zofB/q2AgnZlmoMuH5fMHB2+Ta61I9aD7sNm+woZpx6iH+5vb38chdSoYRvOtSqlH72YQ==} + engines: {node: '>=18.*'} + hasBin: true + pnpm@12.3.4: resolution: {integrity: sha512-lhqkH7B32joEpEHZ+OFevAyW2o73ELLrZ7+e58sGEOq9SPH9hfUc/+c4RnhfoPh8VqOocqHYk/hEZ0G1zORUVw==} engines: {node: '>=18.*'} @@ -87,6 +95,17 @@ snapshots: '@pnpm/exe.win32-x64@12.3.4': optional: true + '@pnpm/exe@12.3.4': + optionalDependencies: + '@pnpm/exe.darwin-arm64': 12.3.4 + '@pnpm/exe.darwin-x64': 12.3.4 + '@pnpm/exe.linux-arm64': 12.3.4 + '@pnpm/exe.linux-arm64-musl': 12.3.4 + '@pnpm/exe.linux-x64': 12.3.4 + '@pnpm/exe.linux-x64-musl': 12.3.4 + '@pnpm/exe.win32-arm64': 12.3.4 + '@pnpm/exe.win32-x64': 12.3.4 + pnpm@12.3.4: optionalDependencies: '@pnpm/exe.darwin-arm64': 12.3.4 diff --git a/tools/manual_api_docs/blocks/boundary.md b/tools/manual_api_docs/blocks/boundary.md new file mode 100644 index 00000000000..9add56ebc54 --- /dev/null +++ b/tools/manual_api_docs/blocks/boundary.md @@ -0,0 +1,32 @@ +IMPORTANT: The `@boundary` block is in [developer preview](reference/releases#developer-preview). It's ready for you to try, but it may change before it is stable. + +The `@boundary` block is a control flow mechanism that lets you intercept and handle rendering errors in templates. + +## Syntax + +```angular-html +@boundary { + +} @error { + +} +``` + +## Description + +The `@boundary` block encapsulates its content and catches any errors that occur during the initial render or subsequent change detection cycles of its child views. If an error is caught, the framework stops rendering the main view and instead renders the fallback UI provided in the `@error` block. + +You can capture the error object by declaring a variable in the `@error` block, for example `@error (let err)`. + +You can use multiple `@error` blocks with `when` clauses to conditionally render different fallbacks based on the error type, with a final fallback `@error` block at the end. You can also access a `$reset` function to attempt re-rendering the boundary content. + +```angular-html +@boundary { + +} @error (let err; retry = $reset; when isNetworkError(err)) { + + +} @error { + +} +```