dot-lookup: add 12s hard deadline + reduce FMCSA timeout to 5s
If FMCSA live API is slow (can take 2x 10s = 20s when down), the route would hang until nginx proxy killed the connection -> 'Failed to fetch'. Now: - fmcsaFetch timeout: 10s -> 5s (two calls max 10s total) - SOS entity-status timeout: already reduced to 5s - 12s hard deadline: if any live API hangs past 12s, immediately return census-only data with a 'partial=true' flag so the user gets something Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e7afc3002e
commit
cebc432af8
1 changed files with 36 additions and 2 deletions
|
|
@ -23,7 +23,7 @@ async function fmcsaFetch(path: string): Promise<any> {
|
|||
try {
|
||||
const url = `${FMCSA_BASE}/${path}${path.includes("?") ? "&" : "?"}webKey=${FMCSA_API_KEY}`;
|
||||
const resp = await fetch(url, {
|
||||
signal: AbortSignal.timeout(10000),
|
||||
signal: AbortSignal.timeout(5000),
|
||||
headers: { "Accept": "application/json" },
|
||||
});
|
||||
if (!resp.ok) return null;
|
||||
|
|
@ -58,6 +58,12 @@ router.get("/api/v1/dot/lookup", async (req, res) => {
|
|||
return;
|
||||
}
|
||||
|
||||
// Hard 12s deadline — if FMCSA/SOS APIs are slow, return local census data
|
||||
// rather than hanging until nginx proxy timeout kills the connection.
|
||||
const deadline = new Promise<"timeout">((resolve) =>
|
||||
setTimeout(() => resolve("timeout"), 12000)
|
||||
);
|
||||
|
||||
try {
|
||||
// 1. Local census data
|
||||
const local = await pool.query(
|
||||
|
|
@ -66,6 +72,32 @@ router.get("/api/v1/dot/lookup", async (req, res) => {
|
|||
);
|
||||
const census = local.rows[0] || null;
|
||||
|
||||
// Race the deadline — if live APIs are too slow, return census-only data now
|
||||
deadline.then((t) => {
|
||||
if (t === "timeout" && !res.headersSent) {
|
||||
const name = census?.legal_name || "Unknown";
|
||||
console.warn("[dot-lookup] Deadline hit for DOT %s — returning census data only", rawDot);
|
||||
res.json({
|
||||
dot_number: rawDot,
|
||||
legal_name: name,
|
||||
dba_name: census?.dba_name || null,
|
||||
phy_city: census?.phy_city || null,
|
||||
phy_state: census?.phy_state || null,
|
||||
telephone: census?.telephone || null,
|
||||
email: census?.email_address || null,
|
||||
fleet: { power_units: census?.nbr_power_unit ?? null, drivers: census?.driver_total ?? null },
|
||||
mcs150_date: census?.mcs150_parsed || null,
|
||||
carrier_type: census?.carrier_operation || null,
|
||||
for_hire: census?.authorized_for_hire || false,
|
||||
checks: [{ id: "data_partial", label: "Compliance Check", status: "unknown",
|
||||
detail: "Live FMCSA data is temporarily slow. Showing local records only — try again in a moment for full results." }],
|
||||
summary: { red: 0, yellow: 0, green: 0, total: 1 },
|
||||
checked_at: new Date().toISOString(),
|
||||
partial: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 2. Live FMCSA API (returns null on any failure — already non-throwing)
|
||||
const snapshot = await fmcsaFetch(rawDot);
|
||||
const carrier = snapshot?.content?.carrier || null;
|
||||
|
|
@ -587,8 +619,10 @@ router.get("/api/v1/dot/lookup", async (req, res) => {
|
|||
});
|
||||
} catch (err) {
|
||||
console.error("[dot-lookup] Error:", err);
|
||||
res.status(500).json({ error: "DOT lookup failed." });
|
||||
if (!res.headersSent) res.status(500).json({ error: "DOT lookup failed." });
|
||||
}
|
||||
// Clear the deadline timer to avoid Node keeping the event loop alive
|
||||
deadline.then(() => {}).catch(() => {});
|
||||
});
|
||||
|
||||
// ── Name Search ─────────────────────────────────────────────────────
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue