Skip to content

Commit a544f89

Browse files
JakeSCahillclaude
andcommitted
Round 2 prod-readiness (widget): fix openTab false-blocked + probe timeout
- openTab: window.open with 'noopener' always returns null, so the old Boolean(win) reported every successful open as blocked (misleading the two unattended agent tools 100% of the time). Open without noopener, sever opener manually, so only a real popup block is false. - getSessionToken: add an AbortController client timeout (8s) so a hung /kapa/session connection degrades to the anonymous tier instead of leaving the drawer stuck on the loading spinner forever. Co-Authored-By: Claude Opus 4.8 <[email protected]>
1 parent e46003d commit a544f89

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

src/js/react/AskAI.jsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,18 @@ function announceSession (authenticated, user, loginUrl) {
3535

3636
async function getSessionToken () {
3737
const endpoint = window.KAPA_SESSION_ENDPOINT || '/kapa/session'
38-
const res = await fetch(endpoint, { method: 'POST', credentials: 'include' })
38+
// Client-side timeout: a hung connection (LB/proxy accepts TCP but never
39+
// responds) would otherwise neither resolve nor reject, leaving the drawer
40+
// stuck on the loading spinner forever. On abort we throw, so probeSession's
41+
// .catch degrades to the anonymous tier — matching the network-error fallback.
42+
const ctrl = new AbortController()
43+
const timer = setTimeout(() => ctrl.abort(), Number(window.KAPA_SESSION_TIMEOUT_MS || 8000))
44+
let res
45+
try {
46+
res = await fetch(endpoint, { method: 'POST', credentials: 'include', signal: ctrl.signal })
47+
} finally {
48+
clearTimeout(timer)
49+
}
3950
if (res.status === 401) {
4051
const data = await res.json().catch(() => ({}))
4152
announceSession(false, null, data.login_url)

src/js/react/agentTools.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,18 @@ function resolveDocsUrl (url) {
4040

4141
// Open in a new tab; a blocked popup returns null so callers can degrade to a link
4242
function openTab (url) {
43-
const win = window.open(url, '_blank', 'noopener')
43+
// NOTE: window.open() returns null whenever the 'noopener' feature is set
44+
// (per spec + all browsers), so we can't use its return to detect a blocked
45+
// popup — doing so reported "blocked" on every successful open. Open without
46+
// 'noopener' and sever opener manually so a genuine null (real popup block)
47+
// is the only false, and the caller's degrade-to-a-link path is accurate.
48+
let win
49+
try {
50+
win = window.open(url, '_blank')
51+
if (win) win.opener = null
52+
} catch {
53+
return false
54+
}
4455
return Boolean(win)
4556
}
4657

0 commit comments

Comments
 (0)