Skip to content

fix(tx-broadcast): use 422 over 502 to bypass CF error-page interception#305

Merged
rz1989s merged 1 commit into
mainfrom
fix/issue-299-followup-422-for-cf-passthrough
May 23, 2026
Merged

fix(tx-broadcast): use 422 over 502 to bypass CF error-page interception#305
rz1989s merged 1 commit into
mainfrom
fix/issue-299-followup-422-for-cf-passthrough

Conversation

@rz1989s
Copy link
Copy Markdown
Member

@rz1989s rz1989s commented May 23, 2026

Summary

Final follow-up to #299. PR #304 normalized the polling-fallback rejection so the route catches TransactionFailedOnChainError and emits a structured envelope — verified working via in-VPS curl:

status: 502
content-type: application/json; charset=utf-8
body: {"error":{"code":"TX_FAILED_ON_CHAIN","message":"...","signature":"...","err":{"InstructionError":[0,{"Custom":1}]}}}

But the same request via https://sipher-api.sip-protocol.org/api/tx/broadcast returns a Cloudflare-branded 502 Bad gateway HTML page — CF's default behavior is to replace origin's body for 5xx codes. The FE never sees our JSON envelope.

This PR switches the status to 422 Unprocessable Entity, which CF passes through unchanged. The semantics also fit: the request was syntactically valid; the on-chain program could not process it.

Test plan

  • pnpm typecheck clean across root + sdk + app + agent
  • pnpm vitest run tests/routes/tx-broadcast.test.ts — 13 passed
  • Post-merge: re-run smoke against prod; expect 422 TX_FAILED_ON_CHAIN envelope visible end-to-end through Cloudflare.

Notes

  • Origin headers (vary, content-type, content-length) were all correct on 502; this is CF's hard-coded error page substitution, not an origin issue.
  • Body shape unchanged — only the status code changed. FE consumers branching on error.code continue to work; consumers branching on numeric status need to add 422 to their "tx failed at program level" bucket.
  • All other status codes (200, 400, 401, 504 for blockheight expired) remain unchanged.

In-VPS curl against the freshly-deployed PR #304 image confirms the route
correctly returns the structured envelope:

  status: 502
  content-type: application/json; charset=utf-8
  body: {"error":{"code":"TX_FAILED_ON_CHAIN","message":"...",
                  "signature":"...","err":{"InstructionError":[0,{"Custom":1}]}}}

But the same request via `https://sipher-api.sip-protocol.org/api/tx/broadcast`
returns a Cloudflare-branded `502 Bad gateway` HTML page — CF's default
behavior is to replace the origin's response body for 5xx status codes.
The FE never sees our JSON envelope.

Switching the status to 422 (Unprocessable Entity) bypasses CF's error
substitution. The semantics also fit better: the request was syntactically
valid; the on-chain program could not process it. The body shape is
unchanged.

Updates the corresponding route test to expect 422.

10 sendWithRetry / 13 tx-broadcast tests pass. Typecheck clean across root,
sdk, app, agent.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sipher Ready Ready Preview, Comment May 23, 2026 4:12pm

@rz1989s rz1989s merged commit 59210f1 into main May 23, 2026
8 checks passed
@rz1989s rz1989s deleted the fix/issue-299-followup-422-for-cf-passthrough branch May 23, 2026 16:15
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.

1 participant