mirror of
https://github.com/ChromeDevTools/chrome-devtools-mcp.git
synced 2026-09-28 11:22:57 +08:00
fix: preserve underlying error message in input tool actions (#2792)
`handleActionError` previously rewrote every `click`/`hover`/`fill`/`fill_form` failure as "The element did not become interactive within the configured timeout", discarding the real cause. It now keeps that wording only for an actual Puppeteer `TimeoutError` and surfaces the underlying message otherwise, so e.g. selecting a missing option now reports `Could not find option with text "..."`.
This commit is contained in:
Vendored
+1
@@ -51,6 +51,7 @@ export {
|
||||
KnownDevices,
|
||||
CDPSessionEvent,
|
||||
ScreenRecorder,
|
||||
TimeoutError,
|
||||
} from 'puppeteer-core';
|
||||
export {default as puppeteer} from 'puppeteer-core';
|
||||
export type * from 'puppeteer-core';
|
||||
|
||||
+8
-2
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import type {McpContext} from '../McpContext.js';
|
||||
import {zod} from '../third_party/index.js';
|
||||
import {TimeoutError, zod} from '../third_party/index.js';
|
||||
import type {ElementHandle, KeyInput} from '../third_party/index.js';
|
||||
import type {TextSnapshotNode} from '../types.js';
|
||||
import {parseKey} from '../utils/keyboard.js';
|
||||
@@ -35,8 +35,14 @@ const submitKeySchema = zod
|
||||
|
||||
function handleActionError(error: unknown, uid: string) {
|
||||
logger?.('failed to act using a locator', error);
|
||||
const reason =
|
||||
error instanceof TimeoutError
|
||||
? 'The element did not become interactive within the configured timeout.'
|
||||
: error instanceof Error
|
||||
? error.message
|
||||
: String(error);
|
||||
throw new Error(
|
||||
`Failed to interact with the element with uid ${uid}. The element did not become interactive within the configured timeout.`,
|
||||
`Failed to interact with the element with uid ${uid}. ${reason}`,
|
||||
{
|
||||
cause: error,
|
||||
},
|
||||
|
||||
@@ -588,6 +588,40 @@ describe('input', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('reports why filling out a select failed', async () => {
|
||||
await withMcpContext(async (response, context, args) => {
|
||||
const page = context.getSelectedMcpPage().pptrPage;
|
||||
await page.setContent(
|
||||
html`<select
|
||||
><option value="v1">one</option
|
||||
><option value="v2">two</option></select
|
||||
>`,
|
||||
);
|
||||
context.getSelectedMcpPage().textSnapshot = await TextSnapshot.create(
|
||||
context.getSelectedMcpPage(),
|
||||
);
|
||||
await assert.rejects(
|
||||
() =>
|
||||
fill(args).handler(
|
||||
{
|
||||
params: {
|
||||
// Options are matched by their text, not their value.
|
||||
uid: '1_1',
|
||||
value: 'v2',
|
||||
},
|
||||
page: context.getSelectedMcpPage(),
|
||||
},
|
||||
response,
|
||||
context,
|
||||
),
|
||||
{
|
||||
message:
|
||||
'Failed to interact with the element with uid 1_1. Could not find option with text "v2"',
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('fills out a select option with an empty value by text', async () => {
|
||||
await withMcpContext(async (response, context, args) => {
|
||||
const page = context.getSelectedMcpPage().pptrPage;
|
||||
|
||||
Reference in New Issue
Block a user