Uh oh!
There was an error while loading. Please reload this page.
fix(sdk): broadcast failover for browser errors + similar-entries limit - #817
Conversation
callRPCBroadcast only retried on Node.js pre-connection codes
(ECONNREFUSED, ENOTFOUND, etc.), which never appear in the browser.
When a node's CDN returned an HTML error page (e.g. Cloudflare tunnel
1033) or the browser blocked the response with CORS, fetch surfaced a
plain TypeError("Failed to fetch") or a SyntaxError from res.json(), so
the broadcast threw immediately with no failover to the next node.
- Add isBroadcastSafeToRetry that also accepts TypeError network
failures from Chromium/Firefox/Safari, JSON parse errors from HTML
interstitial bodies, and NodeError (HTTP 429/5xx).
- jsonRPCCall now treats any 5xx as NodeError (was 503 only), so 502 /
504 / 520-530 reach the retry path with a typed error instead of a
generic SyntaxError downstream.
- Retrying the same signed tx across nodes is safe because Hive
mempools dedupe by trx_id; broadcastOperations signs exactly once.
- Tests cover browser TypeError, HTML 530, HTML 502, RPCError
(must NOT failover), and all-nodes-down traversal.No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (12)
📒 Files selected for processing (8)
📝 WalkthroughWalkthroughSDK 2.2.20 refactors broadcast failover to distinguish browser network errors, HTML interstitials, and pre-connection failures from JSON-RPC errors and abort-like timeouts, ensuring proper node switching without ambiguous retries. HTTP 5xx responses are consistently treated as node-level failures. The similar-entries query limit increases from 12 to 50. ChangesBroadcast failover and similar entries updates
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
packages/sdk/src/hive-tx/helpers/call.spec.tsOops! Something went wrong! :( ESLint: 8.57.1 YAMLException: Cannot read config file: /packages/sdk/eslint.config.mjs 2 | packages/sdk/src/hive-tx/helpers/call.tsOops! Something went wrong! :( ESLint: 8.57.1 YAMLException: Cannot read config file: /packages/sdk/eslint.config.mjs 2 | packages/sdk/src/modules/search/queries/get-similar-entries-query-options.spec.tsOops! Something went wrong! :( ESLint: 8.57.1 YAMLException: Cannot read config file: /packages/sdk/eslint.config.mjs 2 |
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 |
Greptile SummaryThis PR bundles two SDK fixes: a broadened broadcast failover that handles browser network errors and HTTP 5xx interstitials (replacing the Node.js-only pre-connection check), and a bump of
Confidence Score: 5/5Safe to merge. The broadcast failover expansion is well-reasoned, AbortError/TimeoutError are correctly excluded from the retry path, and the 5xx NodeError promotion prevents guesswork on HTML interstitial bodies. Both changes are narrow and well-tested. The retry-safety logic has been carefully constrained — RPCError is fast-pathed out before health recording, AbortError falls through to the non-retry branch, and the new 5xx NodeError promotion removes the ambiguous SyntaxError path. The limit bump is a one-line config change with a matching spec update. No files require special attention. Important Files Changed
Reviews (4): Last reviewed commit: "chore: apply changeset versioning for PR..." | Re-trigger Greptile |
Uh oh!
There was an error while loading. Please reload this page.
The 6-month recency filter drops most semantic neighbours that HiveSense returns (it ranks by embedding similarity with no recency bias), and the search-api primary path currently yields 0 hits for tag-filtered queries in production, so HiveSense is effectively the sole source. With the cap at 12, the recency filter routinely collapsed the result set below the 3-result render threshold and the strip hid entirely on most posts. Spec assertion updated to mirror the new limit.
Addresses two review notes on the failover widening: 1. jsonRPCCall JSDoc still listed "NodeError for HTTP 429/503" after the 5xx generalization. Now reads "HTTP 429/5xx" so the doc matches the code. 2. Add a spec asserting that an AbortError-style timeout makes callRPCBroadcast throw on the first node without trying the next. Without this guard a future refactor of isBroadcastSafeToRetry could silently allow timeout failover — that's the one ambiguous case where the node may have received the tx and a second-node "duplicate transaction" RPCError would mask the original success.
Uh oh!
There was an error while loading. Please reload this page.
Two unrelated SDK fixes bundled per request — separate commits so they can be reverted independently.
1. Broaden broadcast failover for browser-side errors
callRPCBroadcastonly retried on Node.js pre-connection codes (ECONNREFUSED,ENOTFOUND,EHOSTUNREACH,EAI_AGAIN), which never appear in the browser. When a public Hive node's CDN returned an HTML error page (e.g. CF tunnel 1033 → 530, or a 502/520-528 interstitial) or the browser blocked the response with CORS, fetch surfaced aTypeError("Failed to fetch")or the downstreamres.json()threwSyntaxError— both fell throughisPreConnectionError(e) === falseand the broadcast threw immediately with no failover to the next node, so any single sick node could break broadcasts site-wide.Reproduced today against a public node returning Cloudflare error 1033 — browser console showed a CORS failure on the broadcast call and no second-node attempt was made.
Changes
isBroadcastSafeToRetry(e)replacesisPreConnectionError(e). Accepts:TypeError("Failed to fetch")(Chromium),"NetworkError when attempting to fetch"(Firefox),"Load failed"(Safari).SyntaxError/ generic JSON-parse messages from HTML interstitial bodies.NodeError(HTTP 429/5xx surfaced byjsonRPCCall).RPCError— real blockchain rejections must not failover.jsonRPCCallnow treats any5xxasNodeError(was503only), so 502 / 504 / 520-530 reach the retry path with a typed error instead of a genericSyntaxErrordownstream.Retrying the same signed tx across nodes is safe:
broadcastOperationssigns exactly once andcallRPCBroadcastreuses that payload across attempts; Hive's mempool dedupes bytrx_id.Notes
callRPC(read path) is untouched — it already wraps around all nodes via the retry budget.callRPCBroadcastdirectly).2. Raise
SIMILAR_ENTRIES_LIMITfrom 12 to 50The 6-month recency filter drops most semantic neighbours that HiveSense returns (it ranks by embedding similarity with no recency bias), and the search-api primary path currently yields 0 hits for tag-filtered queries in production, so HiveSense is effectively the sole source. With the cap at 12, the recency filter routinely collapsed the result set below the 3-result render threshold and the suggestions strip hid entirely on most posts.
Spec assertion updated to mirror the new limit.
Test plan
pnpm --filter @ecency/sdk test— all 364 tests pass (5 new incall.spec.ts)TypeError→ failover; CF HTML 530 → failover; CF HTML 502 (tunnel 1033) → failover;RPCErrordoes not failover; all-nodes-fail traverses each node exactly onceget-similar-entries-query-options.spec.tsupdated assertion (12 → 50)Summary by CodeRabbit
Bug Fixes
Improvements