fix: Truth-Scan robust gegen Seiten-Timeouts (Retry) + --skip-onchain für Re-Runs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 09:38:43 +00:00
parent 0696565840
commit b03c03ee62

View File

@@ -12,11 +12,13 @@ const { values: args } = parseArgs({
options: {
'from-block': { type: 'string', default: '20600000' }, // ≈ Sep 2024, vor den ersten WLFI-Treasury-Käufen
'truth-pages': { type: 'string', default: '300' },
'skip-onchain': { type: 'boolean', default: false }, // für Re-Runs nach Truth-Abbruch (Inserts sind idempotent)
},
});
// ── On-chain ──
const fromBlock = Number(args['from-block']);
if (!args['skip-onchain']) {
const head = await getBlockNumber();
console.log(`On-chain-Scan Block ${fromBlock}${head} (${head - fromBlock} Blöcke, ~${Math.ceil((head - fromBlock) / 5000)} Requests)`);
let onchainCount = 0;
@@ -43,6 +45,7 @@ for (let from = fromBlock; from <= head; from += STEP) {
await Bun.sleep(150);
}
console.log(`On-chain: ${onchainCount} Events`);
}
// ── Truth (best effort, letzte N Archiv-Seiten à 10 Posts) ──
// Markup verifiziert 2026-06-12: Seite hat 10 Posts, je ein <div class="status"> (exakt).
@@ -68,10 +71,23 @@ function parseEasternTime(s: string): number {
const offsetH = m ? Number(m[1]) : -5;
return utcGuess - offsetH * 3600_000; // ET 9:49 PM = UTC 9:49 PM (4h) = 01:49 nächster Tag
}
/** Seiten-Fetch mit 3 Versuchen (Timeouts/Netzfehler dürfen den Scan nicht crashen). */
async function fetchPage(p: number): Promise<string | null> {
for (let attempt = 1; attempt <= 3; attempt++) {
try {
const res = await fetch(`https://trumpstruth.org/?page=${p}`, { signal: AbortSignal.timeout(20_000) });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.text();
} catch (err) {
console.warn(`Seite ${p}, Versuch ${attempt}/3 fehlgeschlagen:`, err instanceof Error ? err.message : err);
await Bun.sleep(2000 * attempt);
}
}
return null;
}
for (let p = 1; p <= pages; p++) {
const res = await fetch(`https://trumpstruth.org/?page=${p}`, { signal: AbortSignal.timeout(20_000) });
if (!res.ok) { console.warn(`Seite ${p}: HTTP ${res.status} — Truth-Scan endet hier`); break; }
const html = await res.text();
const html = await fetchPage(p);
if (html === null) { console.warn(`Seite ${p}: dauerhaft nicht erreichbar — Truth-Scan endet hier (best effort)`); break; }
// Split auf exaktes class="status" (nicht \b) — gibt genau 10 Post-Blöcke je Seite.
// Vorsicht: class="status\b würde auch status__header, status__body etc. treffen (138 statt 10).
const blocks = html.split(/class="status"/).slice(1);