Skip to content

Retry Squidrouter route requests that fail at the gateway - #1383

Merged
ebma merged 5 commits into
stagingfrom
fix/squidrouter-gateway-retry
Sep 20, 2026
Merged

ebma merged 5 commits into
stagingfrom
fix/squidrouter-gateway-retry

Conversation

@ebma

@ebma ebma commented Sep 20, 2026

Copy link
Copy Markdown
Member

Why

The nightly e2e run 35485932144 failed in the live quote smoke step: production POST /v1/quotes (BRL → USDT on Polygon) answered 500 Internal server error. Prod logs for that request:

error: Error fetching route from Squidrouter API: {}
error  Failed to fetch route: Unknown error
error  Error creating quote {"errorType":"internal_error"}

Squidrouter's /route endpoint (behind Cloudflare and a load balancer) returned a non-JSON 5xx. squidFetch collapsed the body to {} and the status was not logged, so the log could not say what Squid actually returned. The SELL quote one second later succeeded, and the same BUY works now.

This is not a one-off: production logged 518 of these unparseable Squid errors in the last 14 days (~37/day, ~1.5/hour, evenly spread), each one a user-facing 500. The nightly probe simply caught one.

What

  • squidFetch keeps a non-JSON error body as text, and the route error log now includes the HTTP status, so the next occurrence shows HTTP 502 "<html>…" instead of {}.
  • getRouteInternalWithRetry reuses the existing retry-once path (previously only for 429 rate limits) for a 5xx with a non-JSON body, after 1s. Squid's own deterministic JSON errors (e.g. the ~1000/day "Low liquidity" responses) are not retried.

Tests

  • gateway 502 then success → route returned, fetch called twice (fails on the old code)
  • Squid JSON 500 → not retried, message surfaced

packages/shared: 176 pass. Biome clean.

Notes

  • The smoke test itself is unchanged; it caught a real production defect.
  • The nightly probes production too, so it only stops tripping on this once the fix reaches main with the next release.

A non-JSON error response from Squidrouter (a Cloudflare or load-balancer
error page) was collapsed to `{}` and the HTTP status was not logged, so
production logs showed "Error fetching route from Squidrouter API: {}"
with no way to tell what the upstream actually returned.
The nightly e2e smoke test failed because production's POST /v1/quotes
answered 500: Squidrouter's /route endpoint returned a non-JSON 5xx from
the gateway in front of it. Production logs show this ~1-2 times per hour,
each one a user-facing 500, while the same request succeeds a second later.

Extend the existing retry-once path (previously only for rate limits) to a
5xx whose body is not Squid's JSON error shape. Squid's own deterministic
errors, such as low liquidity, keep failing fast without a retry.
@netlify

netlify Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for vortexfi canceled.

Name Link
🔨 Latest commit f8c6c61
🔍 Latest deploy log https://app.netlify.com/projects/vortexfi/deploys/6aaf89444ffffa00081486a7

@netlify

netlify Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for vortex-sandbox ready!

Name Link
🔨 Latest commit f8c6c61
🔍 Latest deploy log https://app.netlify.com/projects/vortex-sandbox/deploys/6aaf8944bf99630008862f5a
😎 Deploy Preview https://deploy-preview-1383--vortex-sandbox.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for vrtx-dashboard canceled.

Name Link
🔨 Latest commit f8c6c61
🔍 Latest deploy log https://app.netlify.com/projects/vrtx-dashboard/deploys/6aaf8946ded76b0008fcac88

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Body-read failures bypass the retry path, and the normative security specification remains inconsistent with the new behavior.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Improves Squidrouter route resilience and diagnostics for transient gateway failures.

Changes:

  • Preserves non-JSON error bodies and logs HTTP status.
  • Retries non-JSON 5xx route failures once.
  • Adds regression coverage for gateway and Squid JSON errors.
File Description
packages/​shared/​src/​services/​squidrouter/​route.ts Adds error diagnostics and transient retry handling.
packages/​shared/​src/​services/​squidrouter/​route.test.ts Tests retry and non-retry behavior.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/shared/src/services/squidrouter/route.ts Outdated
Comment thread packages/shared/src/services/squidrouter/route.ts
…e read

`response.text()` rejects when the gateway truncates the error stream.
That escaped as a bare TypeError, losing the HTTP status and skipping the
gateway retry, whereas the previous `.json().catch()` still produced an
HttpError. Treat an unreadable body as empty so the status is logged and
a 5xx is still retried.
…y spec

The Squid integration spec said only 429s are retried and every other
error fails fast. It also described the 429 handling as exponential
backoff, whereas `getRoute` retries once after the advertised retryAfter.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The security specification’s audit checklist still incorrectly describes 429 handling as exponential backoff.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
Resolved since last review (2)

Comment thread docs/security-spec/05-integrations/squid-router.md
@ebma
ebma merged commit 0f77e06 into staging Sep 20, 2026
6 checks passed
@ebma
ebma deleted the fix/squidrouter-gateway-retry branch September 20, 2026 07:51
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