const TRANSIENT_HTTP_STATUSES = new Set([408, 429, 502, 503, 504]); function isNetworkOrTimeout(error) { const code = String(error?.code || "").toUpperCase(); return ( code.includes("ETIMEDOUT") || code.includes("ECONNRESET") || code.includes("ENOTFOUND") || code.includes("EAI_AGAIN") || code.includes("ECONNABORTED") ); } function extractUberCode(responseData, fallbackStatus) { if (!responseData || typeof responseData !== "object") { return fallbackStatus ? `http_${fallbackStatus}` : "unknown_error"; } return responseData.code || responseData.error || responseData.error_code || "unknown_error"; } function extractUberMessage(responseData, fallbackMessage) { if (!responseData || typeof responseData !== "object") { return fallbackMessage || "Unknown error"; } return responseData.message || responseData.error_description || fallbackMessage || "Unknown error"; } function normalizeUberError(error) { const status = error?.response?.status || 500; const responseData = error?.response?.data; const code = extractUberCode(responseData, status); const message = extractUberMessage(responseData, error?.message); const transient = TRANSIENT_HTTP_STATUSES.has(status) || isNetworkOrTimeout(error); const normalized = new Error(`Uber API request failed: ${status} ${code}`); normalized.status = status; normalized.code = code; normalized.transient = transient; normalized.details = responseData || { message }; return normalized; } function isRetryableUberError(error) { if (error?.transient === true) { return true; } if (error?.response?.status && TRANSIENT_HTTP_STATUSES.has(error.response.status)) { return true; } return isNetworkOrTimeout(error); } module.exports = { normalizeUberError, isRetryableUberError };