From b3556489619824fb32ccf3e6ddd99d36da6bba08 Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 24 Sep 2025 21:05:30 +0200 Subject: [PATCH] fix: avoid reporting page close errors as errors --- src/McpContext.ts | 6 ++---- src/tools/ToolDefinition.ts | 3 +++ src/tools/pages.ts | 12 ++++++++++-- tests/tools/pages.test.ts | 15 ++++++--------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/McpContext.ts b/src/McpContext.ts index 035f71845..49d6e7ccc 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -13,7 +13,7 @@ import { SerializedAXNode, PredefinedNetworkConditions, } from 'puppeteer-core'; -import {Context} from './tools/ToolDefinition.js'; +import {CLOSE_PAGE_ERROR, Context} from './tools/ToolDefinition.js'; import {Debugger} from 'debug'; import {NetworkCollector, PageCollector} from './PageCollector.js'; import fs from 'node:fs/promises'; @@ -133,9 +133,7 @@ export class McpContext implements Context { } async closePage(pageIdx: number): Promise { if (this.#pages.length === 1) { - throw new Error( - 'Unable to close the last page in the browser. It is fine to keep the last page open.', - ); + throw new Error(CLOSE_PAGE_ERROR); } const page = this.getPageByIdx(pageIdx); this.setSelectedPageIdx(0); diff --git a/src/tools/ToolDefinition.ts b/src/tools/ToolDefinition.ts index be07fdbb6..926a104cb 100644 --- a/src/tools/ToolDefinition.ts +++ b/src/tools/ToolDefinition.ts @@ -79,3 +79,6 @@ export function defineTool( ) { return definition; } + +export const CLOSE_PAGE_ERROR = + 'The last open page cannot be closed. It is fine to keep it open.'; diff --git a/src/tools/pages.ts b/src/tools/pages.ts index be6ec2360..a9bfb7348 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -5,7 +5,7 @@ */ import z from 'zod'; -import {defineTool} from './ToolDefinition.js'; +import {CLOSE_PAGE_ERROR, defineTool} from './ToolDefinition.js'; import {ToolCategories} from './categories.js'; export const listPages = defineTool({ @@ -58,7 +58,15 @@ export const closePage = defineTool({ ), }, handler: async (request, response, context) => { - await context.closePage(request.params.pageIdx); + try { + await context.closePage(request.params.pageIdx); + } catch (err) { + if (err.message === CLOSE_PAGE_ERROR) { + response.appendResponseLine(err.message); + } else { + throw err; + } + } response.setIncludePages(true); }, }); diff --git a/tests/tools/pages.test.ts b/tests/tools/pages.test.ts index 5cad3b6e0..7af62f414 100644 --- a/tests/tools/pages.test.ts +++ b/tests/tools/pages.test.ts @@ -56,15 +56,12 @@ describe('pages', () => { it('cannot close the last page', async () => { await withBrowser(async (response, context) => { const page = context.getSelectedPage(); - try { - await closePage.handler({params: {pageIdx: 0}}, response, context); - assert.fail('not reached'); - } catch (err) { - assert.strictEqual( - err.message, - 'Unable to close the last page in the browser. It is fine to keep the last page open.', - ); - } + await closePage.handler({params: {pageIdx: 0}}, response, context); + assert.deepStrictEqual( + response.responseLines[0], + `The last open page cannot be closed. It is fine to keep it open.`, + ); + assert.ok(response.includePages); assert.ok(!page.isClosed()); }); });