Repository navigation
fix(hooks): prevent placing an order with stale appData after adding a hook - #7908
tenderdeve wants to merge 8 commits into
Conversation
…a hook When a pre/post-hook is added, appData is rebuilt asynchronously. Placing the order before that rebuild finished used a stale appData doc, so the hook could be missing from the order. Track the hooks the current appData was built from and block the trade flow context until they match the latest hooks, so placement always includes the added hook. Fixes cowprotocol#7872
|
@tenderdeve is attempting to deploy a commit to the cow-dev Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThe change tracks the hooks used to build current app data, exposes a synchronization check, and blocks trade-flow activation until current hooks match the latest app-data build. ChangesApp-data synchronization
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant AppDataInfoUpdater
participant AppDataAtoms
participant TradeFlowContext
AppDataInfoUpdater->>AppDataAtoms: record hooks used for current app-data build
TradeFlowContext->>AppDataAtoms: compare current hooks with built hooks
AppDataAtoms-->>TradeFlowContext: return synchronization status
TradeFlowContext->>TradeFlowContext: activate only when synchronized
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/cowswap-frontend/src/modules/appData/updater/AppDataInfoUpdater.ts`:
- Around line 84-88: Update the buildAppData success/failure handling in
AppDataInfoUpdater so setAppDataBuiltWithHooks(typedHooks) runs only after a
successful build. When buildAppData throws and appDataInfo falls back to
getAppData(), reset the built-hooks marker to undefined instead of recording
typedHooks.
- Around line 84-88: Update the async updater around buildAppData to capture the
current execution/request ID before awaiting it, then only perform
setAppDataInfo and setAppDataBuiltWithHooks when that ID is still current. Apply
the same guard in the finally path before recording typedHooks, reusing an
existing request ID rather than creating a timestamp.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 31449099-6998-4f52-8d99-8b98edd5822f
📒 Files selected for processing (5)
apps/cowswap-frontend/src/modules/appData/hooks.tsapps/cowswap-frontend/src/modules/appData/index.tsapps/cowswap-frontend/src/modules/appData/state/atoms.tsapps/cowswap-frontend/src/modules/appData/updater/AppDataInfoUpdater.tsapps/cowswap-frontend/src/modules/tradeFlow/hooks/useTradeFlowContext.ts
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
elena-zh
left a comment
There was a problem hiding this comment.
Hey @tenderdeve , the app preview crashes on opening
deepEqual calls Object.keys(), which throws on the undefined appData hooks atoms present on first render, crashing the app on load. Treat both-undefined (or same reference) as in sync and one-sided undefined as out of sync before falling back to the deep comparison.
|
@elena-zh good catch — the crash was in the new sync check. Fixed in 0ea0d89: it now treats both-undefined (no hooks) as in sync and only deep-compares when both sides are present, so there's nothing to throw on load. Order placement is still blocked during the stale window when hooks were actually changed. |
|
@tenderdeve I kindly ask you to check the coderabbit comments: |
Move the built-with-hooks marker out of the finally block: record typedHooks only after a successful build, and clear it on the fallback path since the default document may omit the newly added hooks. Also guard both writes with a run id so a superseded, slower build can't overwrite fresher appData.
|
@shoom3301 addressed both CodeRabbit comments in cd56bbc. The built-with-hooks marker was in a Also guarded both writes with a run id ( |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/cowswap-frontend/src/modules/appData/updater/AppDataInfoUpdater.ts`:
- Around line 91-94: In the catch block of the app-data updater, replace catch
(e: any) with catch (err: unknown), assign const error = normalizeError(err)
before logging, and pass the normalized error to console.error. Remove the TODO
and eslint suppression, reusing the existing normalizeError utility.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 34c1ac16-18ce-44f3-8852-9052a146db27
📒 Files selected for processing (1)
apps/cowswap-frontend/src/modules/appData/updater/AppDataInfoUpdater.ts
|
Addressed the remaining CodeRabbit comment in |
|
|
@tenderdeve thank you for the contribution! |
Summary
Fixes #7872.
When a pre/post-hook is added, appData is rebuilt asynchronously (
AppDataInfoUpdater→buildAppData). If the user was quick to open the confirm modal and place the order, the trade flow captured the previous appData doc — built before the hook existed — so the placed order was missing the hook.Fix
appDataInfowas built from in a newappDataBuiltWithHooksAtom, set alongside everyappDataInfoupdate.useIsAppDataHooksInSync()comparing the latest hooks against the ones the current appData was built from.useTradeFlowContexton that check, so the order can't be placed until appData reflects the added hook. The window is just the async rebuild (a few ms), after which placement re-enables normally.Testing
undefinedon both sides, so the check is always in sync.Summary by CodeRabbit