Skip to content

Update web_core with Signal improvements and error handling#875

Merged
gspencergoog merged 4 commits intogoogle:mainfrom
gspencergoog:web_core_is_signal
Mar 18, 2026
Merged

Update web_core with Signal improvements and error handling#875
gspencergoog merged 4 commits intogoogle:mainfrom
gspencergoog:web_core_is_signal

Conversation

@gspencergoog
Copy link
Collaborator

Description

This PR updates renderers/web_core with Signal-based improvements to the DataContext and core models to support reactive state updates.

Changes

  • renderers/web_core/src/rendering/data-context.ts: Refactored DataContext to better leverage Signal patterns.
  • renderers/web_core/src/state/*.ts: Updated state models and subscription logic to prevent reactive leaks and align with signals.
  • renderers/web_core/src/errors.ts: Unified action/error message processor handling.

Impact & Risks

  • No Breaking Changes to existing backward-compatible APIs; sets foundation for v0.9 rendering pipelines.

Testing

  1. Run and verify unit tests inside renderers/web_core.

@github-project-automation github-project-automation bot moved this to Todo in A2UI Mar 17, 2026
@gspencergoog gspencergoog changed the title Update web_core with Signal improvements and error handling Update web_core with Signal improvements and error handling Mar 17, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces significant improvements to the reactive capabilities of web_core, particularly around Signal-based state management and error handling in DataContext. The introduction of the isSignal utility for robust type checking and the new error handling within reactive effects are great steps forward.

I've identified one area for improvement in the new error handling logic: there's a case where non-A2uiExpressionError errors in reactive evaluations could be silently swallowed, making debugging difficult. I've suggested a change to ensure all errors are reported.

Overall, these are solid changes that enhance the stability and predictability of the reactive system. Addressing the feedback will further improve the robustness of the error handling.

Comment on lines +266 to 277
} catch (e: any) {
if (e instanceof A2uiExpressionError) {
this.surface.dispatchError({
code: "EXPRESSION_ERROR",
message: e.message,
expression: e.expression,
details: e.details,
});
}
// In reactive mode, we should not throw. Instead, reset the signal value.
resultSig.value = undefined;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The current implementation of the catch block only handles A2uiExpressionError. Any other type of error thrown during the reactive evaluation will be silently swallowed. This can make debugging very difficult as there will be no indication of what went wrong, other than the signal's value becoming undefined.

It would be more robust to handle other error types as well, for example by dispatching a generic error to the surface.

} catch (e: any) {
  if (e instanceof A2uiExpressionError) {
    this.surface.dispatchError({
      code: "EXPRESSION_ERROR",
      message: e.message,
      expression: e.expression,
      details: e.details,
    });
  } else {
    this.surface.dispatchError({
      code: "EXPRESSION_ERROR",
      message: e.message ?? `An unexpected error occurred in function ${call.call}.`,
      expression: call.call,
      details: { stack: e.stack },
    });
  }
  // In reactive mode, we should not throw. Instead, reset the signal value.
  resultSig.value = undefined;
}

Extracted redundant try-catch handling blocks into a dedicated `dispatchExpressionError` private helper to reduce code duplication in `evaluateFunctionReactive` and `resolveSignal` scopes.

Updated `resolveDynamicValue` to utilize `evaluateFunctionReactive` directly for its function invoker path setup to remove separate fall-through flows.

Added and adapted corresponding tests to assert correctly against generic error dispatches instead of original literal fallbacks.
@gspencergoog gspencergoog merged commit 6976be4 into google:main Mar 18, 2026
11 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in A2UI Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants