From 328774339b8f756f1caf5f2efe778e21526dd2f8 Mon Sep 17 00:00:00 2001 From: accius Date: Sat, 31 Jan 2026 18:50:15 -0500 Subject: [PATCH] added logging for dxpedition errors --- public/index.html | 7 ++++++- server.js | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/public/index.html b/public/index.html index 7e5f1bf..b8e7dac 100644 --- a/public/index.html +++ b/public/index.html @@ -1102,13 +1102,18 @@ useEffect(() => { const fetchDXpeditions = async () => { try { + console.log('[DXpeditions] Fetching...'); const response = await fetch('/api/dxpeditions'); + console.log('[DXpeditions] Response status:', response.status); if (response.ok) { const result = await response.json(); + console.log('[DXpeditions] Received:', result.dxpeditions?.length, 'entries'); setData(result); + } else { + console.error('[DXpeditions] Failed:', response.status); } } catch (err) { - console.error('DXpedition fetch error:', err); + console.error('[DXpeditions] Fetch error:', err); } finally { setLoading(false); } diff --git a/server.js b/server.js index f90f5fd..18ef867 100644 --- a/server.js +++ b/server.js @@ -151,22 +151,32 @@ let dxpeditionCache = { data: null, timestamp: 0, maxAge: 30 * 60 * 1000 }; // 3 app.get('/api/dxpeditions', async (req, res) => { try { const now = Date.now(); + console.log('[DXpeditions] API called'); // Return cached data if fresh if (dxpeditionCache.data && (now - dxpeditionCache.timestamp) < dxpeditionCache.maxAge) { + console.log('[DXpeditions] Returning cached data:', dxpeditionCache.data.dxpeditions?.length, 'entries'); return res.json(dxpeditionCache.data); } // Fetch NG3K ADXO plain text version (easier to parse) + console.log('[DXpeditions] Fetching from NG3K...'); const response = await fetch('https://www.ng3k.com/Misc/adxoplain.html'); - if (!response.ok) throw new Error('Failed to fetch NG3K'); + if (!response.ok) { + console.log('[DXpeditions] NG3K fetch failed:', response.status); + throw new Error('Failed to fetch NG3K: ' + response.status); + } const text = await response.text(); + console.log('[DXpeditions] Received', text.length, 'bytes from NG3K'); + const dxpeditions = []; // Split by the bullet separator used in the plain text version const entries = text.split(/\s*ยท\s*/); + console.log('[DXpeditions] Found', entries.length, 'entries to parse'); + let parseCount = 0; for (const entry of entries) { if (!entry.trim() || entry.length < 20) continue; @@ -180,6 +190,14 @@ app.get('/api/dxpeditions', async (req, res) => { // Date pattern at the start: "Jan 1, 2026-Feb 16, 2026" or "Jan 1-16, 2026" const dateMatch = entry.match(/^([A-Za-z]+\s+\d+[^D]*?)(?=\s*DXCC:)/i); + // Log first few entries for debugging + if (parseCount < 3) { + console.log('[DXpeditions] Entry sample:', entry.substring(0, 150)); + console.log('[DXpeditions] DXCC match:', dxccMatch?.[1]); + console.log('[DXpeditions] Call match:', callMatch?.[1]); + } + parseCount++; + // Must have both DXCC and Callsign to be valid if (!callMatch || !dxccMatch) continue; @@ -274,16 +292,19 @@ app.get('/api/dxpeditions', async (req, res) => { timestamp: new Date().toISOString() }; + console.log('[DXpeditions] Parsed', dxpeditions.length, 'valid entries,', result.active, 'active,', result.upcoming, 'upcoming'); + // Cache the result dxpeditionCache.data = result; dxpeditionCache.timestamp = now; res.json(result); } catch (error) { - console.error('DXpedition API error:', error.message); + console.error('[DXpeditions] API error:', error.message); // Return cached data if available, even if stale if (dxpeditionCache.data) { + console.log('[DXpeditions] Returning stale cache'); return res.json({ ...dxpeditionCache.data, stale: true }); }