fix: prevent infinite loading screen by adding sweep timeouts (#32)
fix: prevent infinite loading screen by adding sweep timeouts
This commit is contained in:
@@ -43,13 +43,22 @@ import { briefing as space } from './sources/space.mjs';
|
||||
// === Tier 5: Live Market Data ===
|
||||
import { briefing as yfinance } from './sources/yfinance.mjs';
|
||||
|
||||
const SOURCE_TIMEOUT_MS = 30_000; // 30s max per individual source
|
||||
|
||||
export async function runSource(name, fn, ...args) {
|
||||
const start = Date.now();
|
||||
let timer;
|
||||
try {
|
||||
const data = await fn(...args);
|
||||
const dataPromise = fn(...args);
|
||||
const timeoutPromise = new Promise((_, reject) => {
|
||||
timer = setTimeout(() => reject(new Error(`Source ${name} timed out after ${SOURCE_TIMEOUT_MS / 1000}s`)), SOURCE_TIMEOUT_MS);
|
||||
});
|
||||
const data = await Promise.race([dataPromise, timeoutPromise]);
|
||||
return { name, status: 'ok', durationMs: Date.now() - start, data };
|
||||
} catch (e) {
|
||||
return { name, status: 'error', durationMs: Date.now() - start, error: e.message };
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +66,7 @@ export async function fullBriefing() {
|
||||
console.error('[Crucix] Starting intelligence sweep — 27 sources...');
|
||||
const start = Date.now();
|
||||
|
||||
const results = await Promise.allSettled([
|
||||
const allPromises = [
|
||||
// Tier 1: Core OSINT & Geopolitical
|
||||
runSource('GDELT', gdelt),
|
||||
runSource('OpenSky', opensky),
|
||||
@@ -94,7 +103,11 @@ export async function fullBriefing() {
|
||||
|
||||
// Tier 5: Live Market Data
|
||||
runSource('YFinance', yfinance),
|
||||
]);
|
||||
];
|
||||
|
||||
// Each runSource has its own 30s timeout, so allSettled will resolve
|
||||
// within ~30s even if APIs hang. Global timeout is a safety net.
|
||||
const results = await Promise.allSettled(allPromises);
|
||||
|
||||
const sources = results.map(r => r.status === 'fulfilled' ? r.value : { status: 'failed', error: r.reason?.message });
|
||||
const totalMs = Date.now() - start;
|
||||
|
||||
@@ -37,11 +37,15 @@ export async function getSeries(seriesIds, opts = {}) {
|
||||
if (apiKey) payload.registrationkey = apiKey;
|
||||
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), 15000);
|
||||
const res = await fetch(base, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timer);
|
||||
return await res.json();
|
||||
} catch (e) {
|
||||
return { error: e.message };
|
||||
|
||||
Reference in New Issue
Block a user