Skip to content

Enrich incompatible update invariant messages with diagnostics#681

Merged
vladar merged 4 commits into
vladar/add-regression-tests-for-updateobjfrom
vladar-ideal-fishstick
Jun 26, 2026
Merged

Enrich incompatible update invariant messages with diagnostics#681
vladar merged 4 commits into
vladar/add-regression-tests-for-updateobjfrom
vladar-ideal-fishstick

Conversation

@vladar

@vladar vladar commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Goal: better error messages for invariants that may happen on incorrect manual cache operations.

Update the invariant-violation messages across updateObject, updateTree, traverse, and draftHelpers to follow a consistent broader-to-specific shape:

Failed to update "query BaseFeedQuery" at path listContainer.items.0.value (in Entity): expected CompositeList, got ObjectDifference

vrazuvaev and others added 3 commits June 25, 2026 13:23
Reformat invariant-violation messages across updateObject, updateTree,
traverse, and draftHelpers to follow a consistent broader-to-specific
shape: operation debugName, then path, then the enclosing node __typename,
then the observed value (including the incoming value's type where it can
be recovered). All path and type extraction is wrapped in try/catch since
the cache state is already corrupt when an invariant fires, and no node
keys are interpolated to avoid exposing entity identifiers.

Adds co-located unit tests for every new message with named operations and
exact-message assertions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown

📊 Benchmark Analysis Report

🔍 Found 1 significant change(s)

🎯 Same Configuration Comparisons

Comparing against baseline with the same cache configuration

Benchmark ID Configuration Execution Memory
write-no-changes_0 Default 🟢 3911.10 bytes → 3713.36 bytes (-5.1%)

Threshold: 5% change


Updated: 2026-06-25T15:55:14.994Z

The enriched diagnostic messages walk the data path and look up __typenames,
which is expensive. Passing them as the second argument to assert() built the
full string on every call, including the success path, causing a 7-10%
regression in the write-array benchmarks.

Guard each message-bearing assert with an explicit condition check so the
message builder only runs when the invariant actually fails, matching the
existing if (!cond) { assert(false, ...) } pattern already used in traverse.ts
and draftHelpers.ts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vladar vladar marked this pull request as ready for review June 26, 2026 08:37
@vladar vladar merged commit 13eba11 into vladar/add-regression-tests-for-updateobj Jun 26, 2026
4 checks passed
@vladar vladar deleted the vladar-ideal-fishstick branch June 26, 2026 08:37
vladar added a commit that referenced this pull request Jun 26, 2026
* Report incompatible object diff invariants

* Remove obsolete Apollo cache regression test

* Enrich incompatible update invariant messages with diagnostics (#681)

* Enrich incompatible update invariant messages with diagnostics

Reformat invariant-violation messages across updateObject, updateTree,
traverse, and draftHelpers to follow a consistent broader-to-specific
shape: operation debugName, then path, then the enclosing node __typename,
then the observed value (including the incoming value's type where it can
be recovered). All path and type extraction is wrapped in try/catch since
the cache state is already corrupt when an invariant fires, and no node
keys are interpolated to avoid exposing entity identifiers.

Adds co-located unit tests for every new message with named operations and
exact-message assertions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix lint: normalize line endings and formatting

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Change files

* Defer invariant message construction to the failure path

The enriched diagnostic messages walk the data path and look up __typenames,
which is expensive. Passing them as the second argument to assert() built the
full string on every call, including the success path, causing a 7-10%
regression in the write-array benchmarks.

Guard each message-bearing assert with an explicit condition check so the
message builder only runs when the invariant actually fails, matching the
existing if (!cond) { assert(false, ...) } pattern already used in traverse.ts
and draftHelpers.ts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: vrazuvaev <vrazuvaev@microsoft.com_msteamsmdb>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: vrazuvaev <vrazuvaev@microsoft.com_msteamsmdb>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant