fix(browser): clarify DevToolsActivePort attach failures

This commit is contained in:
Peter Steinberger
2026-04-21 08:11:11 +01:00
parent 9f054ee05b
commit 7b1871b99b
4 changed files with 42 additions and 5 deletions

View File

@@ -123,6 +123,23 @@ export function createProfileAvailability({
});
};
const formatChromeMcpAttachFailure = (lastError: unknown): string => {
const detail = lastError instanceof Error ? ` Last error: ${lastError.message}` : "";
const message = lastError instanceof Error ? lastError.message : "";
if (message.includes("DevToolsActivePort") || message.includes("Could not connect to Chrome")) {
return (
`Chrome MCP existing-session attach for profile "${profile.name}" could not connect to Chrome. ` +
"Enable remote debugging in the browser inspect page, keep the browser open, approve the attach prompt, and retry. " +
'If you do not need your signed-in browser session, use the managed "openclaw" profile instead.' +
detail
);
}
return (
`Chrome MCP existing-session attach for profile "${profile.name}" timed out waiting for tabs to become available.` +
` Approve the browser attach prompt, keep the browser open, and retry.${detail}`
);
};
const reconcileProfileRuntime = async (): Promise<void> => {
const profileState = getProfileState();
const reconcile = profileState.reconcile;
@@ -181,11 +198,7 @@ export function createProfileAvailability({
}
await new Promise((r) => setTimeout(r, CHROME_MCP_ATTACH_READY_POLL_MS));
}
const detail = lastError instanceof Error ? ` Last error: ${lastError.message}` : "";
throw new BrowserProfileUnavailableError(
`Chrome MCP existing-session attach for profile "${profile.name}" timed out waiting for tabs to become available.` +
` Approve the browser attach prompt, keep the browser open, and retry.${detail}`,
);
throw new BrowserProfileUnavailableError(formatChromeMcpAttachFailure(lastError));
};
const ensureBrowserAvailable = async (): Promise<void> => {

View File

@@ -75,6 +75,7 @@ beforeEach(() => {
afterEach(() => {
vi.unstubAllEnvs();
vi.useRealTimers();
});
describe("browser server-context existing-session profile", () => {
@@ -134,4 +135,25 @@ describe("browser server-context existing-session profile", () => {
);
expect(chromeMcp.closeChromeMcpSession).toHaveBeenCalledWith("chrome-live");
});
it("surfaces DevToolsActivePort attach failures instead of a generic tab timeout", async () => {
vi.useFakeTimers();
fs.mkdirSync("/tmp/brave-profile", { recursive: true });
vi.mocked(chromeMcp.listChromeMcpTabs).mockRejectedValue(
new Error(
"Could not connect to Chrome. Check if Chrome is running. Cause: Could not find DevToolsActivePort for chrome at /tmp/brave-profile/DevToolsActivePort",
),
);
const state = makeState();
const ctx = createBrowserRouteContext({ getState: () => state });
const live = ctx.forProfile("chrome-live");
const pending = live.ensureBrowserAvailable();
const assertion = expect(pending).rejects.toThrow(
/could not connect to Chrome.*managed "openclaw" profile.*DevToolsActivePort/s,
);
await vi.advanceTimersByTimeAsync(8_000);
await assertion;
});
});