From e0be6468d40cc69177d8d55e2d6b2dd2aaeb8d9e Mon Sep 17 00:00:00 2001 From: justin Date: Sun, 31 May 2026 10:19:10 -0500 Subject: [PATCH] dot-lookup: fix 'Failed to fetch' caused by SOS timeout exceeding nginx proxy limit Two WORKER_URL/entity-status calls both had 20s timeouts; worst case 40s total response time exceeds nginx proxy_read_timeout, dropping the connection and causing the browser to show 'Failed to fetch'. Also wraps fmcsaFetch calls explicitly so FMCSA API failure still returns full local census data. - AbortSignal.timeout(20000) -> 5000 on both SOS entity-status calls - fmcsaFetch carrier + authority calls wrapped in individual try/catch Co-Authored-By: Claude Sonnet 4.6 --- api/src/routes/dot-lookup.ts | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/api/src/routes/dot-lookup.ts b/api/src/routes/dot-lookup.ts index d72b941..2dd581d 100644 --- a/api/src/routes/dot-lookup.ts +++ b/api/src/routes/dot-lookup.ts @@ -66,13 +66,23 @@ router.get("/api/v1/dot/lookup", async (req, res) => { ); const census = local.rows[0] || null; - // 2. Live FMCSA API - const snapshot = await fmcsaFetch(rawDot); - const carrier = snapshot?.content?.carrier || null; + // 2. Live FMCSA API — wrapped so a timeout or outage still returns census data + let carrier: any = null; + try { + const snapshot = await fmcsaFetch(rawDot); + carrier = snapshot?.content?.carrier || null; + } catch { + // FMCSA live API unavailable — continue with local census data + } - // 3. Authority check - const authorityData = await fmcsaFetch(`${rawDot}/authority`); - const authorities = (authorityData?.content || []).map((a: any) => a.carrierAuthority); + // 3. Authority check — also non-fatal + let authorities: any[] = []; + try { + const authorityData = await fmcsaFetch(`${rawDot}/authority`); + authorities = (authorityData?.content || []).map((a: any) => a.carrierAuthority); + } catch { + // Authority lookup failed — skip, checks will use census data where possible + } if (!census && !carrier) { res.status(404).json({ error: `DOT# ${rawDot} not found.` }); @@ -483,7 +493,7 @@ router.get("/api/v1/dot/lookup", async (req, res) => { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ entity_name: name, state_code: state }), - signal: AbortSignal.timeout(20000), + signal: AbortSignal.timeout(5000), }); if (sosResp.ok) { sosStatus = (await sosResp.json()) as { found?: boolean; status?: string; error?: string }; @@ -688,7 +698,7 @@ router.post("/api/v1/dot/name-check", async (req, res) => { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ entity_name: name, state_code: stateCode }), - signal: AbortSignal.timeout(20000), + signal: AbortSignal.timeout(5000), }).then(r => r.json()) : Promise.resolve({ skipped: true }),