diff --git a/src/bootstrap.ts b/src/bootstrap.ts index c486055..c92352f 100644 --- a/src/bootstrap.ts +++ b/src/bootstrap.ts @@ -147,10 +147,28 @@ export async function bootstrap(config: Config, logger: Logger): Promise(); const onRequest = (request: import('playwright').Request) => { if (done) return; try { const url = new URL(request.url()); - if (!MATRIX_HOST_RE.test(url.hostname)) return; + const isMatrix = MATRIX_HOST_RE.test(url.hostname); const headers = request.headers(); const auth = headers['authorization'] || headers['Authorization']; - if (!auth || !auth.toLowerCase().startsWith('bearer ')) return; - const token = auth.slice('bearer '.length).trim(); + const hasAuth = !!auth && auth.toLowerCase().startsWith('bearer '); + const entry = seenHosts.get(url.hostname) ?? { count: 0, sawAuth: false }; + entry.count += 1; + if (hasAuth) entry.sawAuth = true; + seenHosts.set(url.hostname, entry); + if (!isMatrix) return; + if (!hasAuth) return; + const token = auth!.slice('bearer '.length).trim(); if (!token) return; const homeserver = `${url.protocol}//${url.host}`; done = true; @@ -105,7 +115,32 @@ export async function extractMatrixCredentials( ), ); - const captured = await Promise.race([credsPromise, timeout]); + let captured: MatrixCredentials; + try { + captured = await Promise.race([credsPromise, timeout]); + } catch (err) { + // On timeout, surface enough info to tell the three failure modes apart: + // (a) chat.reddit.com never loaded → page.url() still about:blank, almost no hosts + // (b) page loaded, no Matrix host hit → reddit hosts present, no matrix.* + // (c) Matrix hit, but no Authorization → matrix.* present with sawAuth: false + try { + const finalUrl = page.url(); + const hostSummary = Array.from(seenHosts.entries()) + .map(([host, info]) => `${host}=${info.count}${info.sawAuth ? '*' : ''}`) + .join(', '); + logger.error( + `[matrix] timeout diagnostics: finalUrl=${finalUrl} hosts=[${hostSummary || 'none'}]`, + ); + const shotDir = path.dirname(cachePath); + if (!fs.existsSync(shotDir)) fs.mkdirSync(shotDir, { recursive: true }); + const shotPath = path.join(shotDir, 'matrix-debug.png'); + await page.screenshot({ path: shotPath, fullPage: true }).catch(() => undefined); + logger.error(`[matrix] saved debug screenshot to ${shotPath}`); + } catch (diagErr) { + logger.warn('[matrix] failed to collect timeout diagnostics:', diagErr); + } + throw err; + } // Resolve the user_id by calling /whoami so the caller knows who we are. const whoamiRes = await fetchWithTimeout(