From 30ea2bd28e298b18542397e1720706ad0eb0bc43 Mon Sep 17 00:00:00 2001 From: Bas van den Aakster Date: Fri, 14 Nov 2025 21:01:15 +0100 Subject: [PATCH] Add detailed logging for ICE candidate storage and retrieval - Log when ICE candidates are added with offerId, peerId, role, count, timestamp - Log when ICE candidates are requested with peer type, targetRole, since - Log D1 query parameters and result counts - Use consistent timestamp for all candidates in a batch - Log first candidate timestamp vs since parameter for debugging --- src/app.ts | 3 +++ src/storage/d1.ts | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/app.ts b/src/app.ts index fd8ed36..b8fffa2 100644 --- a/src/app.ts +++ b/src/app.ts @@ -498,14 +498,17 @@ export function createApp(storage: Storage, config: Config) { if (offer.peerId === peerId) { // Offerer wants answerer's candidates targetRole = 'answerer'; + console.log(`[ICE GET] Offerer ${peerId} requesting answerer ICE candidates for offer ${offerId}, since=${since}, answererPeerId=${offer.answererPeerId}`); } else if (offer.answererPeerId === peerId) { // Answerer wants offerer's candidates targetRole = 'offerer'; + console.log(`[ICE GET] Answerer ${peerId} requesting offerer ICE candidates for offer ${offerId}, since=${since}, offererPeerId=${offer.peerId}`); } else { return c.json({ error: 'Not authorized to view ICE candidates for this offer' }, 403); } const candidates = await storage.getIceCandidates(offerId, targetRole, since); + console.log(`[ICE GET] Found ${candidates.length} candidates for offer ${offerId}, targetRole=${targetRole}, since=${since}`); return c.json({ offerId, diff --git a/src/storage/d1.ts b/src/storage/d1.ts index c09af3f..3b6355f 100644 --- a/src/storage/d1.ts +++ b/src/storage/d1.ts @@ -244,6 +244,9 @@ export class D1Storage implements Storage { role: 'offerer' | 'answerer', candidates: RTCIceCandidateInit[] ): Promise { + const now = Date.now(); + console.log(`[D1] addIceCandidates: offerId=${offerId}, peerId=${peerId}, role=${role}, count=${candidates.length}, timestamp=${now}`); + // D1 doesn't have transactions, so insert one by one for (const cand of candidates) { await this.db.prepare(` @@ -254,7 +257,7 @@ export class D1Storage implements Storage { peerId, role, JSON.stringify(cand), // Store full object as JSON - Date.now() + now ).run(); } @@ -280,13 +283,15 @@ export class D1Storage implements Storage { query += ' ORDER BY created_at ASC'; + console.log(`[D1] getIceCandidates query: offerId=${offerId}, targetRole=${targetRole}, since=${since}`); const result = await this.db.prepare(query).bind(...params).all(); + console.log(`[D1] getIceCandidates result: ${result.results?.length || 0} rows`); if (!result.results) { return []; } - return result.results.map((row: any) => ({ + const candidates = result.results.map((row: any) => ({ id: row.id, offerId: row.offer_id, peerId: row.peer_id, @@ -294,6 +299,12 @@ export class D1Storage implements Storage { candidate: JSON.parse(row.candidate), // Parse JSON back to object createdAt: row.created_at, })); + + if (candidates.length > 0) { + console.log(`[D1] First candidate createdAt: ${candidates[0].createdAt}, since: ${since}`); + } + + return candidates; } async getTopics(limit: number, offset: number): Promise<{