fix(browser-relay): fallback to cached targetId on target info lookup failure

This commit is contained in:
Mark Musson
2026-02-27 09:37:59 +00:00
committed by Peter Steinberger
parent 3ae8e5ee91
commit 591ff3c1c8

View File

@@ -277,12 +277,24 @@ async function reannounceAttachedTabs() {
}
// Send fresh attach event to relay.
// Split into two try-catch blocks so debugger failures and relay send
// failures are handled independently. Previously, a relay send failure
// would fall into the outer catch and set the badge to 'on' even though
// the relay had no record of the tab — causing every subsequent browser
// tool call to fail with "no tab connected" until the next reconnect cycle.
let targetInfo
try {
const info = /** @type {any} */ (
await chrome.debugger.sendCommand({ tabId }, 'Target.getTargetInfo')
)
const targetInfo = info?.targetInfo
targetInfo = info?.targetInfo
} catch {
// Target.getTargetInfo failed. Preserve at least targetId from
// cached tab state so relay receives a stable identifier.
targetInfo = tab.targetId ? { targetId: tab.targetId } : undefined
}
try {
sendToRelay({
method: 'forwardCDPEvent',
params: {
@@ -301,7 +313,15 @@ async function reannounceAttachedTabs() {
title: 'OpenClaw Browser Relay: attached (click to detach)',
})
} catch {
setBadge(tabId, 'on')
// Relay send failed (e.g. WS closed in the gap between ensureRelayConnection
// resolving and this loop executing). The tab is still valid — leave badge
// as 'connecting' so the reconnect/keepalive cycle will retry rather than
// showing a false-positive 'on' that hides the broken state from the user.
setBadge(tabId, 'connecting')
void chrome.action.setTitle({
tabId,
title: 'OpenClaw Browser Relay: relay reconnecting…',
})
}
}
@@ -769,7 +789,11 @@ async function onDebuggerDetach(source, reason) {
title: 'OpenClaw Browser Relay: re-attaching after navigation…',
})
const delays = [300, 700, 1500]
// Extend re-attach window from 2.5 s to ~7.7 s (5 attempts).
// SPAs and pages with heavy JS can take >2.5 s before the Chrome debugger
// is attachable, causing all three original attempts to fail and leaving
// the badge permanently off after every navigation.
const delays = [200, 500, 1000, 2000, 4000]
for (let attempt = 0; attempt < delays.length; attempt++) {
await new Promise((r) => setTimeout(r, delays[attempt]))