Repository navigation
fix(sdk): stop signature step polling on failure or refund - #1144
pedromcunha-uneven merged 2 commits into
Conversation
|
@erkancamli is attempting to deploy a commit to the Uneven Labs Team on Vercel. A member of the Team first needs to authorize it. |
|
A failure whose details did not contain 'Transaction failed' was retried as a network error until maxAttempts, and a refund status had no branch, so both polled until the timeout and lost the real reason.
The refund branch rejected without setting the item's checkStatus, so the emitted state reported a refund while the item kept its previous status. The transaction and websocket paths set it before rejecting.
c92249d to
b9b9cf9
Compare
|
@pedromcunha thanks for the approval. Is anything else needed from my side before this can be merged? Happy to rebase onto the latest main if that helps. |
|
@pedromcunha friendly follow-up: this still applies cleanly on current main, and nothing has touched these files since your approval. #1143 and #1145 are in the same state. Happy to rebase all three if that makes merging easier. |
|
LGTM, thanks |
| @@ -362,7 +368,12 @@ export async function handleSignatureStepItem({ | |||
| client.log(['Transaction completed successfully'], LogLevel.Verbose) | |||
| return // Success - exit polling | |||
| } else if (res?.data?.status === 'failure') { | |||
There was a problem hiding this comment.
Can we set stepItem.checkStatus = 'failure' here before throwing? The refund branch now does this so it matches the transaction and websocket paths, and the same reason applies to failure. Right now the item stays on pending (or undefined) after a failure. The assertion at signatureStep.test.ts:139 would change to 'failure'.
| @@ -362,7 +368,12 @@ export async function handleSignatureStepItem({ | |||
| client.log(['Transaction completed successfully'], LogLevel.Verbose) | |||
| return // Success - exit polling | |||
| } else if (res?.data?.status === 'failure') { | |||
There was a problem hiding this comment.
FYI: the websocket path doesn't treat failure as final. It waits 2s because the backend can go failure → pending → refund (websocketHandlers.ts:74-89). Polling now stops at the first failure, so that sequence ends with refunded: false. This isn't a regression (on main it timed out) and it matches transaction.ts, so fine to leave. It just means the description's "websocket handlers already treat both as final" isn't quite right.
There was a problem hiding this comment.
Good catch, thanks. Opened #1175 for it: the failure branch now sets stepItem.checkStatus = 'failure' before throwing, with the tests updated.
In
signatureStep.tsstatus polling, afailurethrowsError(res.data.details || 'Transaction failed'), but the catch only rethrows messages containing "Transaction failed" or "Failed to check". Any otherdetailsstring is treated as a network error and retried untilmaxAttempts, and then surfaces asFailed to get an ok response after N attempt(s), losing the real reason.refund, which/intents/status/v3can return, has no branch at all, so it also polls until the timeout.transaction.tsand the websocket handlers already treat both as final (Transaction failed: Refunded). With websocket off by default, every signature based quote with a check endpoint goes through this polling path.The change adds a small
CheckStatusErrorthatfailureand a newrefundbranch throw and the catch rethrows. Request errors, including 4xx such as 429, are still retried as before. A refund now marks the step as refunded like the other paths do.Tests: three cases in
signatureStep.test.ts. The failure with details and the refund cases fail on main (got 'Failed to get an ok response after 5 …') and pass now; the third confirms request errors are still retried.pnpm typecheckpasses. The rest of the sdk suite passes exceptclient.test.ts > Should configure chains dynamically, which calls the live chains API and fails the same way on main in my environment (no outbound access to it).