fix(dart): implement atomic two-pass component validation in MessageProcessor - #2374
fix(dart): implement atomic two-pass component validation in MessageProcessor#2374diegolopezrm wants to merge 2 commits into
Conversation
…rocessor _processUpdateComponents validated and applied components in a single pass, so a batch containing a valid component followed by an invalid one committed the valid one to SurfaceComponentsModel before the error was raised. The surface was left in a half-updated state that no message describes, and the client had no way to recover it. Split the work into two passes, mirroring the Swift implementation: 1. Validation pass, which checks every component in the batch for a required id and, when the component does not already exist, a required component type. Any failure throws and the batch is abandoned without touching surface state. 2. Mutation pass, which runs only once the whole batch has passed. Adds five tests: a fully valid batch still applies; a batch rejected for a missing id or a missing type leaves the surface untouched; a rejected batch does not overwrite components applied by an earlier accepted batch; and updating an existing component without repeating its type keeps working.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces a two-pass processing mechanism in MessageProcessor to ensure transactional integrity when updating components. The first pass validates all components in a batch (checking for missing IDs or missing types for new components) before any mutations are applied in the second pass, preventing the surface from entering a half-updated state. Comprehensive unit tests have been added to verify this behavior under various success and failure scenarios. There are no review comments, and I have no feedback to provide.
|
@googlebot I signed it! |
Summary
Ports the atomic two-pass component validation from #2332 (Swift) to the Dart implementation.
MessageProcessor._processUpdateComponentsvalidated and applied components in a single pass. If an update payload contained a valid component followed by an invalid one, the valid component was already committed toSurfaceComponentsModelwhen the error was raised, leaving the surface in a half-updated state that no message describes and the client has no way to recover.This mirrors the structure #2332 introduced in Swift:
idand, when the component does not already exist, a requiredcomponenttype. Any failure throws and the batch is abandoned without touching surface state.Reproduction
Before this change, the following left
rootcommitted even though the batch was rejected:Behavioural note
The "cannot create a component without a type" check moves from the mutation site into the validation pass. It keeps the same meaning — the type is required only when the component does not already exist, so updating an existing component without repeating its type still works — but it is now evaluated for the whole batch before anything is applied. A test covers that case explicitly so the relaxation is not lost.
Tests
Five tests added to
dart/a2ui_core/test/processor_test.dart:idleaves the surface untouched;componenttype leaves the surface untouched;The three regression tests fail on
mainand pass with this change. The other two guard against over-restriction.dart testindart/a2ui_core: 74 passing (69 before).dart analyzereports the same two pre-existingunnecessary_library_directiveinfos asmainand nothing new.