Skip to content

fix(host): answer PAPI when a host call rejects - #433

Open
BigTava wants to merge 1 commit into
mainfrom
fix/host-provider-answers-rejected-calls
Open

BigTava wants to merge 1 commit into
mainfrom
fix/host-provider-answers-rejected-calls

Conversation

@BigTava

@BigTava BigTava commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • When a host chain call rejects, the provider now answers PAPI with a JSON-RPC error. truapi rejects a call on a timeout, a closed transport or an abort, and the provider answered only from the two arms of .match, which a rejection never reaches.
  • Before this, the request stayed unsettled for good. A one-shot read hung, and a best-block watch waits on its query in flight, so one timed-out storage query stopped the watch with no error.
  • jollity-next phones logged these timeouts on 2026-09-30 for storage, call and unpin requests, as TrUAPI request host:N (wire 3, 3) timed out after 120000ms and the same for methods 4 and 5. Its chest can then stay on its loading screen when one of its reads is the request left unsettled.
  • A new test makes getHeadStorage, unpinHead and getHeadHeader reject and checks that each request gets a -32603 answer. It fails on main with three unhandled rejections.
  • This edits papi-provider.ts next to fix(host): back off synthetic transport-interrupt stops #427, which changes the follow stop path, so whichever lands second may need a small rebase.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

📦 Bundle size impact

Comparing 2026-10-02T20:36:50.059Z → 2026-10-02T20:36:53.830Z

Package Entry Bundled before Bundled after Δ Ship gzip Δ Shake ratio
🟢 @parity/product-sdk . 8.86 MB 8.86 MB +155 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk ./chain 8.61 MB 8.61 MB +153 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk ./cloud-storage 8.79 MB 8.79 MB +159 B (+0.0%) 0 B 12% (was 12%)
🟢 @parity/product-sdk ./core 8.86 MB 8.86 MB +155 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk ./host 181.0 KB 181.2 KB +153 B (+0.1%) 0 B 14% (was 14%)
🟢 @parity/product-sdk ./react 8.87 MB 8.87 MB +155 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk-chain-client . 8.61 MB 8.61 MB +153 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk-cloud-storage . 8.79 MB 8.79 MB +159 B (+0.0%) 0 B 12% (was 12%)
🟢 @parity/product-sdk-host . 181.0 KB 181.2 KB +153 B (+0.1%) +76 B 14% (was 14%)
🟢 @parity/product-sdk-statement-store . 192.2 KB 192.4 KB +153 B (+0.1%) 0 B 5% (was 5%)

Thresholds — 🟡 ≥10% or ≥5.0 KB · 🟠 ≥20% or ≥15.0 KB (bundled). Percentage only applies once the baseline is ≥ 10 KB. Informational — this check never blocks merge.

* a watch that waits on that query stops emitting.
*/
function onRejection(matched: unknown, err: (error: unknown) => void): void {
Promise.resolve(matched).catch(err);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One edge worth knowing about. match is _promise.then(res => res.match(ok, err)), so if the err arm itself throws (it bottoms out at onMessage, which is PAPI supplied and could throw) the match promise rejects and this catch runs the same err a second time, giving a duplicate error frame and a double settle on the operation sites. Very unlikely and not blocking, but it is new behavior from the wrapping, so maybe guard the catch to only fire when neither arm ran.

This branch has not been deployed

No deployments
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.

2 participants