From 7fe755379b2cca9ff64f11f643042d627d4a35b9 Mon Sep 17 00:00:00 2001 From: Honey Date: Mon, 8 Jun 2026 20:57:26 +0200 Subject: [PATCH] fix(events): fix Ticketmaster URL encoding + add error logging Colons in startDateTime were being percent-encoded which Ticketmaster may reject. Also log errors/status so backend logs reveal the cause when no events appear. Co-Authored-By: Claude Sonnet 4.6 --- backend/novasonic-server.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/backend/novasonic-server.js b/backend/novasonic-server.js index 3d3bcc1..b99e478 100644 --- a/backend/novasonic-server.js +++ b/backend/novasonic-server.js @@ -317,20 +317,24 @@ app.get('/api/itunes/:endpoint', (req, res) => { app.get('/api/events/:artist', (req, res) => { const key = CONFIG.ticketmasterKey; - if (!key) return res.json([]); + if (!key) { console.warn('[events] TICKETMASTER_API_KEY not set'); return res.json([]); } const artist = req.params.artist; - const now = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z'); + const now = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z'); // 2024-06-08T12:00:00Z const url = `https://app.ticketmaster.com/discovery/v2/events.json` + `?keyword=${encodeURIComponent(artist)}&classificationName=music` + - `&startDateTime=${encodeURIComponent(now)}&size=20&sort=date%2Casc` + - `&apikey=${encodeURIComponent(key)}`; + `&startDateTime=${now}&size=20&sort=date,asc` + + `&apikey=${key}`; https.get(url, { headers: { 'Accept': 'application/json' } }, upstream => { let body = ''; upstream.on('data', d => body += d); upstream.on('end', () => { try { - const data = JSON.parse(body); - const raw = data?._embedded?.events || []; + const data = JSON.parse(body); + if (upstream.statusCode !== 200 || data.fault || data.errors) { + console.error('[events] Ticketmaster error:', upstream.statusCode, JSON.stringify(data).slice(0, 200)); + return res.json([]); + } + const raw = data?._embedded?.events || []; const events = raw.map(e => { const venue = e._embedded?.venues?.[0] || {}; const start = e.dates?.start || {}; @@ -342,17 +346,18 @@ app.get('/api/events/:artist', (req, res) => { return { datetime: dt, venue: { - name: venue.name || '', + name: venue.name || '', city: venue.city?.name || '', country: venue.country?.name || '', }, offers: e.url ? [{ url: e.url, status: soldOut ? 'unavailable' : 'available' }] : [], }; }).filter(e => e.datetime); + console.log(`[events] ${artist}: ${events.length} events`); res.json(events); - } catch { res.json([]); } + } catch(err) { console.error('[events] parse error:', err); res.json([]); } }); - }).on('error', () => res.json([])); + }).on('error', e => { console.error('[events] request error:', e.message); res.json([]); }); }); app.get('/api/health', (req, res) => {