fix(query-broadcast-client): handle postMessage errors#10770
fix(query-broadcast-client): handle postMessage errors#10770raashish1601 wants to merge 2 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughWraps BroadcastChannel.postMessage calls in a helper that catches sync throws and promise rejections, invokes an optional onBroadcastError callback with the error and message, logs a dev warning with message type and queryHash, adds tests simulating rejection/sync-throw, and adds a changeset for a patch release. ChangesBroadcast postMessage Error Handling
Sequence DiagramsequenceDiagram
participant App as Application Code
participant BQC as broadcastQueryClient
participant Helper as postMessage Helper
participant Chan as BroadcastChannel
participant CB as onBroadcastError Callback
App->>BQC: setQueryData(...ReadableStream...)
BQC->>Helper: postMessage(updated message)
Helper->>Chan: channel.postMessage(message)
Chan-->>Helper: rejects / throws (DataCloneError)
Helper->>CB: onBroadcastError(error, message)
Helper->>Helper: console.warn (dev) with type + queryHash
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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.
🧹 Nitpick comments (1)
packages/query-broadcast-client-experimental/src/__tests__/index.test.ts (1)
64-99: ⚡ Quick winAdd a regression test for synchronous
postMessagethrows.This test only exercises promise rejection. Adding a sibling case where
channel.postMessagethrows synchronously would lock in the try/catch path in the helper.Suggested test addition
+ it('should report synchronous postMessage throws', async () => { + const error = new DOMException('cannot clone', 'DataCloneError') + const onBroadcastError = vi.fn() + const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined) + + broadcastQueryClient({ + queryClient, + broadcastChannel: 'test_channel', + onBroadcastError, + }) + + const channel = broadcastChannelMock.channels[0]! + channel.postMessage.mockImplementation(() => { + throw error + }) + + queryClient.setQueryData(['stream'], new ReadableStream()) + + await vi.waitFor(() => { + expect(onBroadcastError).toHaveBeenCalledWith( + error, + expect.objectContaining({ + type: 'updated', + queryHash: '["stream"]', + queryKey: ['stream'], + }), + ) + }) + + expect(consoleWarnSpy).toHaveBeenCalledWith( + '[broadcastQueryClient] failed to broadcast "updated" for queryHash "["stream"]"', + error, + ) + })🤖 Prompt for 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. In `@packages/query-broadcast-client-experimental/src/__tests__/index.test.ts` around lines 64 - 99, Add a sibling test in the same file that mirrors the existing "should report postMessage rejections..." spec but simulates a synchronous throw from channel.postMessage instead of returning a rejected Promise: create a DOMException, spy on console.warn, call broadcastQueryClient(...) (same args), find broadcastChannelMock.channels[0], set channel.postMessage to a function that throws the error immediately, invoke queryClient.setQueryData(['stream'], new ReadableStream()), then await vi.waitFor to assert onBroadcastError was called with the error and message shape (type: 'updated', queryHash: '["stream"]', queryKey: ['stream']), and assert console.warn was called with the same failure message and error—this locks in the helper's try/catch path for synchronous throws (reference symbols: broadcastQueryClient, broadcastChannelMock, channel.postMessage, onBroadcastError, queryClient.setQueryData).
🤖 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.
Nitpick comments:
In `@packages/query-broadcast-client-experimental/src/__tests__/index.test.ts`:
- Around line 64-99: Add a sibling test in the same file that mirrors the
existing "should report postMessage rejections..." spec but simulates a
synchronous throw from channel.postMessage instead of returning a rejected
Promise: create a DOMException, spy on console.warn, call
broadcastQueryClient(...) (same args), find broadcastChannelMock.channels[0],
set channel.postMessage to a function that throws the error immediately, invoke
queryClient.setQueryData(['stream'], new ReadableStream()), then await
vi.waitFor to assert onBroadcastError was called with the error and message
shape (type: 'updated', queryHash: '["stream"]', queryKey: ['stream']), and
assert console.warn was called with the same failure message and error—this
locks in the helper's try/catch path for synchronous throws (reference symbols:
broadcastQueryClient, broadcastChannelMock, channel.postMessage,
onBroadcastError, queryClient.setQueryData).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e0417935-b2d1-4c3a-b58f-940a70816dc6
📒 Files selected for processing (3)
.changeset/broadcast-client-post-errors.mdpackages/query-broadcast-client-experimental/src/__tests__/index.test.tspackages/query-broadcast-client-experimental/src/index.ts
Summary
Fixes #10542 and #10543.
broadcastQueryClientnow sends cache events through a guardedpostMessagehelper. If the underlyingbroadcast-channelimplementation rejects or throws for a non-cloneable payload, the rejection is handled instead of surfacing as an unhandled rejection. Consumers can also passonBroadcastErrorto log the offending broadcast message in production, while development still gets a queryHash-aware warning.Testing
corepack pnpm --filter @tanstack/query-broadcast-client-experimental exec vitest run src/__tests__/index.test.tscorepack pnpm exec prettier --check .changeset/broadcast-client-post-errors.md packages/query-broadcast-client-experimental/src/index.ts packages/query-broadcast-client-experimental/src/__tests__/index.test.tscorepack pnpm exec eslint --concurrency=auto -c eslint.config.js packages/query-broadcast-client-experimental/src/index.ts packages/query-broadcast-client-experimental/src/__tests__/index.test.tscorepack pnpm exec tsc -p packages/query-broadcast-client-experimental/tsconfig.prod.json --noEmit --pretty falsecorepack pnpm exec tsup src/index.ts --no-config --format cjs,esm --target es2020,node16 --dts --sourcemap --clean --out-dir build/legacy --tsconfig tsconfig.prod.jsongit diff --checkNote: the package
test:types:tscurrentandbuildscripts still hit the existing Windows symlink-placeholder checkout issue forroot.eslint.config.js/root.tsup.config.js, so I validated the changed source with the direct TypeScript andtsup --no-configcommands above.Summary by CodeRabbit
New Features
onBroadcastErrorcallback option to surface broadcast transmission failures.Bug Fixes
Tests
Documentation