fix: harden browser existing-session flows

This commit is contained in:
Peter Steinberger
2026-03-13 23:56:39 +00:00
parent fa05947225
commit 4357cf4e37
11 changed files with 302 additions and 77 deletions

View File

@@ -39,6 +39,7 @@ const DEFAULT_CHROME_MCP_ARGS = [
];
const sessions = new Map<string, ChromeMcpSession>();
const pendingSessions = new Map<string, Promise<ChromeMcpSession>>();
let sessionFactory: ChromeMcpSessionFactory | null = null;
function asRecord(value: unknown): Record<string, unknown> | null {
@@ -144,6 +145,11 @@ function extractMessageText(result: ChromeMcpToolResult): string {
return blocks.find((block) => block.trim()) ?? "";
}
function extractToolErrorMessage(result: ChromeMcpToolResult, name: string): string {
const message = extractMessageText(result).trim();
return message || `Chrome MCP tool "${name}" failed.`;
}
function extractJsonMessage(result: ChromeMcpToolResult): unknown {
const candidates = [extractMessageText(result), ...extractTextContent(result)].filter((text) =>
text.trim(),
@@ -207,8 +213,22 @@ async function getSession(profileName: string): Promise<ChromeMcpSession> {
session = undefined;
}
if (!session) {
session = await (sessionFactory ?? createRealSession)(profileName);
sessions.set(profileName, session);
let pending = pendingSessions.get(profileName);
if (!pending) {
pending = (async () => {
const created = await (sessionFactory ?? createRealSession)(profileName);
sessions.set(profileName, created);
return created;
})();
pendingSessions.set(profileName, pending);
}
try {
session = await pending;
} finally {
if (pendingSessions.get(profileName) === pending) {
pendingSessions.delete(profileName);
}
}
}
try {
await session.ready;
@@ -229,10 +249,14 @@ async function callTool(
): Promise<ChromeMcpToolResult> {
const session = await getSession(profileName);
try {
return (await session.client.callTool({
const result = (await session.client.callTool({
name,
arguments: args,
})) as ChromeMcpToolResult;
if (result.isError) {
throw new Error(extractToolErrorMessage(result, name));
}
return result;
} catch (err) {
sessions.delete(profileName);
await session.client.close().catch(() => {});
@@ -268,6 +292,7 @@ export function getChromeMcpPid(profileName: string): number | null {
}
export async function closeChromeMcpSession(profileName: string): Promise<boolean> {
pendingSessions.delete(profileName);
const session = sessions.get(profileName);
if (!session) {
return false;
@@ -508,5 +533,6 @@ export function setChromeMcpSessionFactoryForTest(factory: ChromeMcpSessionFacto
export async function resetChromeMcpSessionsForTest(): Promise<void> {
sessionFactory = null;
pendingSessions.clear();
await stopAllChromeMcpSessions();
}