Skip to content

feat(core): introduce @boundary control flow and programmatic error handling - #70463

Closed
JeanMeche wants to merge 9 commits into
angular:mainfrom
JeanMeche:error-boundary
Closed

JeanMeche wants to merge 9 commits into
angular:mainfrom
JeanMeche:error-boundary

Conversation

@JeanMeche

@JeanMeche JeanMeche commented Aug 29, 2026 •

Copy link
Copy Markdown
Member

Introduces a declarative way to catch rendering errors in templates using the new @boundary block, preventing local failures from crashing the entire application hierarchy.

@boundary {
  <complex-chart [data]="data" />
} @error (let err = $error; let r = $retry) {
  <p>Failed to load chart: {{err.message}}</p>
  <button (click)="r()">Retry</button>
}

Additionally, this adds programmatic error handling for dynamically created views by introducing an onError option to ViewContainerRef.createComponent,createEmbeddedView and the standalone alone createComponent function:

viewContainerRef.createComponent(DynamicComponent, {
  onError: (err: Error, details: ErrorDetails) => {
    console.error('Component rendering failed:', err);
    // Render an alternative UI or log metrics
  }
});

Additional changes:

  • ErrorHandler can now implement onViewError(err, details) to receive rich metadata about caught boundary errors.

Note: most of design & implementation was done by @alxhub.
Note2: Docs on the feature will be addressed in a follow-up PR.

@angular-robot angular-robot Bot added detected: feature PR contains a feature commit area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime area: server Issues related to server-side rendering area: language-service Issues related to Angular's VS Code language service labels Aug 29, 2026
@ngbot ngbot Bot added this to the Backlog milestone Aug 29, 2026
@JeanMeche
JeanMeche force-pushed the error-boundary branch 3 times, most recently from 2a70304 to c388ce6 Compare August 29, 2026 00:57
@splincode

Copy link
Copy Markdown
Contributor

Was @try {} / @catch {} considered? Why was @boundary {} / @error {} preferred?

@JeanMeche

Copy link
Copy Markdown
Member Author

Error Boundaries are a common concept in frontend frameworks and try/catch felt more "imperative" to us.

@JeanMeche
JeanMeche marked this pull request as ready for review August 31, 2026 16:59
@JeanMeche
JeanMeche requested a review from crisbeto August 31, 2026 16:59
@pullapprove
pullapprove Bot requested review from atscott and kirjs August 31, 2026 16:59
@JeanMeche
JeanMeche requested review from leonsenft and removed request for kirjs August 31, 2026 17:00
@JeanMeche
JeanMeche force-pushed the error-boundary branch 3 times, most recently from cb16745 to dc7ed41 Compare August 31, 2026 17:26
Comment thread packages/core/src/render3/instructions/change_detection.ts Outdated
Comment thread packages/core/src/error_handler.ts
Comment thread packages/language-service/src/outlining_spans.ts
Comment thread goldens/public-api/core/index.api.md Outdated
Comment thread packages/core/src/error_handler.ts Outdated
Comment thread packages/core/src/linker/view_container_ref.ts Outdated
Comment thread packages/core/src/render3/instructions/boundary.ts Outdated
Comment thread packages/core/src/render3/instructions/change_detection.ts Outdated
Comment thread packages/compiler/src/render3/r3_boundaries.ts
Comment thread packages/core/src/error_handler.ts
Comment thread packages/core/test/render3/error_boundary_spec.ts Outdated
Comment thread packages/core/test/render3/error_boundary_spec.ts Outdated
Comment thread packages/core/test/render3/error_boundary_spec.ts
Comment thread packages/compiler-cli/test/ngtsc/boundary_spec.ts Outdated
Comment thread packages/core/src/render3/instructions/control_flow.ts Outdated
Comment thread packages/core/src/render3/instructions/boundary.ts
Comment thread packages/core/src/render3/instructions/boundary.ts Outdated
Comment thread packages/compiler/src/typecheck/ops/expression.ts Outdated
Comment thread packages/language-service/src/template_target.ts Outdated
@JeanMeche
JeanMeche force-pushed the error-boundary branch 3 times, most recently from 48c436e to c742892 Compare September 2, 2026 23:22
Comment thread packages/core/src/error_handler.ts Outdated
import * as t from './r3_ast';

/** Pattern used to identify a boundary `let` parameter. */
const LET_PATTERN = /^(let\s+)(.*)/;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this wasn't resolved?

export interface ErrorDetails {
readonly boundary?: {
readonly type: Type<any>;
readonly reset: () => void;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for: we need to settle on either retry or reset for consistency

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the a precedent anywhere for this? @atscott Didn't you use something similar for reseting/retrying route resources, or was that reloading?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think maybe you're referring to reload, potentially? There was something in there to trigger reloads on resources in an error state.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay. Maybe reset is most appropriate then? reload and retry to me imply some kind of network request operation, whereas reset more accurately reflects the fact that we're simply resetting some internal framework state?

alxhub and others added 6 commits September 8, 2026 21:50
Add the runtime primitives `ɵɵboundaryCreate` and `ɵɵboundaryUpdate` to
the core instructions, which handle synchronous view destruction and
provide the `ON_ERROR` interceptor hooks.

Also include the initial compiler AST representations for the new syntax
including the Lexer tokenization and HTML Parser integration. This lays
the foundational structure for `@boundary` prior to code generation.

Co-authored-by: Matthieu Riegler <kyro38@gmail.com>
Add support for `@boundary` blocks in the template type-checking pipeline.
Add support for the new `@boundary` and `@error` control flow blocks in the Angular Language Service.

This includes:
- Updating outlining spans to handle boundary blocks correctly.
- Adding classification visitor methods for semantic tokens.
- Adding template target visitor methods for navigation and hover support.
- Updating the TextMate grammar to recognize `@boundary` and the `when` clause.
…ation

Added some tests to ensure error boundaries work with SSR and hydration.
@JeanMeche JeanMeche added action: merge The PR is ready for merge by the caretaker target: minor This PR is targeted for the next minor release labels Sep 9, 2026
@crisbeto

crisbeto commented Sep 9, 2026

Copy link
Copy Markdown
Member

This PR was merged into the repository. The changes were merged into the following branches:

@crisbeto crisbeto closed this in f6afb80 Sep 9, 2026
angular-robot pushed a commit to angular-robot/angular that referenced this pull request Sep 9, 2026
angular#70463)

Add the runtime primitives `ɵɵboundaryCreate` and `ɵɵboundaryUpdate` to
the core instructions, which handle synchronous view destruction and
provide the `ON_ERROR` interceptor hooks.

Also include the initial compiler AST representations for the new syntax
including the Lexer tokenization and HTML Parser integration. This lays
the foundational structure for `@boundary` prior to code generation.

Co-authored-by: Matthieu Riegler <kyro38@gmail.com>

PR Close angular#70463
angular-robot pushed a commit to angular-robot/angular that referenced this pull request Sep 9, 2026
…ngular#70463)

Add support for `@boundary` blocks in the template type-checking pipeline.

PR Close angular#70463
angular-robot pushed a commit to angular-robot/angular that referenced this pull request Sep 9, 2026
Add support for the new `@boundary` and `@error` control flow blocks in the Angular Language Service.

This includes:
- Updating outlining spans to handle boundary blocks correctly.
- Adding classification visitor methods for semantic tokens.
- Adding template target visitor methods for navigation and hover support.
- Updating the TextMate grammar to recognize `@boundary` and the `when` clause.

PR Close angular#70463
angular-robot pushed a commit to angular-robot/angular that referenced this pull request Sep 9, 2026
…ation (angular#70463)

Added some tests to ensure error boundaries work with SSR and hydration.

PR Close angular#70463
JeanMeche added a commit to JeanMeche/angular that referenced this pull request Sep 20, 2026
thePunderWoman pushed a commit that referenced this pull request Sep 21, 2026
thePunderWoman pushed a commit that referenced this pull request Sep 21, 2026
medbenmakhlouf added a commit to jsverse/transloco that referenced this pull request Sep 25, 2026
)

* feat(keys-manager): support @boundary/@error error-boundary block

Adds forward-compat support for Angular's upcoming @boundary/@error
error-boundary block (angular/angular#70463, targeted for Angular 22.2),
mirroring the existing @switch/@if handling.

- compiler-compat.ts: guarded TmplAstBoundaryBlock/TmplAstBoundaryErrorBlock
  structural types + type guards, so it compiles today and picks up the
  real compiler exports transparently once shipped.
- utils.ts: wired the new block into the generic block-walker so both
  directiveExtractor and structuralDirectiveExtractor traverse into it
  with no extractor-specific changes.
- compiler-compat.spec.ts: guard-rejection unit tests.
- verify-keys-manager-compat.mts: added a real @boundary/@error fixture,
  gated by a new supportsBoundaryBlock(version) check (mirrors the
  existing supportsGroupedCases gate for Angular 21.1).
- ci.yml: new keys-manager-compat matrix entry pinned to
  '>=22.2.0-next.0 <22.3.0', marked experimental (continue-on-error) since
  it tracks an unreleased Angular prerelease; verified locally against the
  real @angular/compiler@22.2.0-next.7.

* chore(keys-manager): track stable Angular 22.2 in compat matrix

Angular 22.2 is released, so the @boundary/@error support no longer
needs prerelease handling.

- ci.yml: drop the experimental >=22.2.0-next.0 matrix entry; the
  floating '22' entry now resolves to 22.2 and gates merges.
- verify-keys-manager-compat.mts: revert the '='-safe arg parsing and
  the --legacy-peer-deps prerelease handling, no longer needed.
- Reword comments from future to past tense.

* fix(keys-manager): parse compat script args at first =

The script advertises --angular=<range>, but split('=') truncated any
value containing its own '=', such as '>=22.2.0 <22.3.0'. Split each
option at its first '=' only so the full range reaches npm.

* test(keys-manager): add @boundary/@error extraction spec
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: merge The PR is ready for merge by the caretaker area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime area: language-service Issues related to Angular's VS Code language service area: server Issues related to server-side rendering detected: feature PR contains a feature commit target: minor This PR is targeted for the next minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants