ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Playwright WebError:捕获页面中未处理异常的机制与源码解析

Playwright WebError:捕获页面中未处理异常的机制与源码解析 Playwright WebError捕获页面中未处理异常的机制与源码解析【免费下载链接】playwrightPlaywright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright在 Web 自动化测试中页面脚本抛出的未处理异常unhandled exception常常被忽略——它不像网络请求失败那样有明确的返回值却往往是测试失败的真正根源。Playwright 从 v1.38 起提供了WebError类API 文档它代表在页面中抛出的一个未处理异常并通过BrowserContext.webError事件派发。掌握这一机制后你可以在测试中集中监听所有页面上的 JS 异常、断言异常内容、定位异常来源的文件与行列甚至把异常统一上报到日志或监控系统。WebError 是什么上下文级的事件对象WebError是BrowserContext上的一个事件载荷。当浏览器上下文中任意一个页面出现未捕获的 JS 异常时Playwright 客户端会构造一个WebError对象并触发weberror事件。与页面级事件不同这个事件挂载在 context 上一次订阅即可覆盖该上下文下当前与未来创建的所有页面。文档给出的四语言用法如下。JavaScript// Log all uncaught errors to the terminal context.on(weberror, webError { console.log(Uncaught exception: ${webError.error()}); }); // Navigate to a page with an exception. await page.goto(data:text/html,scriptthrow new Error(Test)/script);Java// Log all uncaught errors to the terminal context.onWebError(webError - { System.out.println(Uncaught exception: webError.error()); }); // Navigate to a page with an exception. page.navigate(data:text/html,scriptthrow new Error(Test)/script);Pythonasync# Log all uncaught errors to the terminal context.on(weberror, lambda web_error: print(funcaught exception: {web_error.error})) # Navigate to a page with an exception. await page.goto(data:text/html,scriptthrow new Error(test)/script)Pythonsync# Log all uncaught errors to the terminal context.on(weberror, lambda web_error: print(funcaught exception: {web_error.error})) # Navigate to a page with an exception. page.goto(data:text/html,scriptthrow new Error(test)/script)C#// Log all uncaught errors to the terminal context.WebError (_, webError) { Console.WriteLine(Uncaught exception: webError.Error); };一个值得注意的细节文档示例中的异常是用data:URL 内联脚本抛出的这说明weberror事件不依赖任何真实服务器非常适合写最小可复现的测试。API 详解error()、page() 与 location()WebError类提供三个成员方法覆盖了谁抛的、抛了什么、在哪里抛的三个排查维度方法返回值说明版本error()JavaScript/Python 返回Error对象Java/C# 返回string被抛出的未处理异常本身v1.38page()Page或null产生该异常的页面如能确定v1.38location()对象urlstring、lineint、columnint异常资源的位置行/列号均从 0 开始v1.60error()类型差异error()的返回类型随语言不同而不同文档中该 API 标注了langs: java, csharp的独立签名JavaScript / Python返回一个完整的Error对象可以直接访问.stack、.message等属性。Playwright 客户端内部通过parseError()把服务端序列化的SerializedError还原为本地Error对象见下文源码解析Java / C#返回错误信息的字符串形式便于直接打印或断言。page()可能为 nullpage()返回产生该异常的 Page 对象从源码结构看其类型定义为Page | nullwebError.ts 中private _page: Page | null。返回 null 的场景对应异常发生时页面对象已无法确定归属的情况例如页面在异常派发前已关闭因此断言webError.page()前建议先做判空。location()异常来源精确定位v1.60 新增的location()返回一个定位对象文档中别名为WebErrorLocationurl— 资源 URL例如抛出异常的外部 JS 文件地址line— 资源内的行号从 0 开始column— 资源内的列号从 0 开始。仓库中的测试用例 browsercontext-events.spec.ts 验证了该行为的实际表现测试通过本地 server 提供一个/error.js第 3 行throw new Error(boom)页面script src/error.js加载执行后断言const location webError.location(); expect(location.url).toBe(${server.PREFIX}/error.js); expect(location.line).toBe(2); // 0-based第 3 行 expect(location.column).toBeGreaterThan(0); // column is not consistent across browsers两条重要事实来自该测试line是 0-based源码第 3 行断言为2column值在各浏览器间并不完全一致测试注释明确写出 column is not consistent across browsers因此生产代码中不建议对column做精确相等断言而对url和line的断言则可靠得多。源码解析weberror 事件是如何派发的从客户端源码看整个链路是浏览器端捕获到未处理异常 → 协议层pageError事件 → 客户端BrowserContext接线 → 同时向 context 和 page 派发。协议层定义Playwright 的协议规范 browserContext.yml 中定义了pageError事件pageError: parameters: error: SerializedError page: Page location: type: objecterror以SerializedError形式传输——即异常被序列化包含 name、message、stack后跨进程传递客户端再反序列化还原。客户端接线逻辑核心接线代码位于 browserContext.tsthis._channel.on(pageError, ({ error, page, location }) { const pageObject Page.from(page); const parsedError parseError(error); this.emit(Events.BrowserContext.WebError, new WebError(pageObject, parsedError, location)); if (pageObject) pageObject.emit(Events.Page.PageError, parsedError); });这段代码揭示了两个关键机制双事件派发同一次页面异常会同时触发两个事件——BrowserContext上的weberror事件载荷是完整的WebError对象含 page 与 locationPage上的pageerror事件载荷只是还原后的Error对象本身。也就是说如果你只关心某个具体页面的异常可以直接用page.on(pageerror, ...)如果要跨页面统一收集比如全局日志、异常监控则应使用 context 级的weberror事件。事件名映射WebError常量在 events.ts 中映射为字符串weberror这就是各语言 API 中事件名的来源。WebError 类本体客户端类 webError.ts 非常简洁——它只是持有三个私有字段并暴露只读访问export class WebError implements api.WebError { private _page: Page | null; private _error: Error; private _location: WebErrorLocation; constructor(page: Page | null, error: Error, location: WebErrorLocation) { this._page page; this._error error; this._location location; } page() { return this._page; } error() { return this._error; } location() { return this._location; } }从源码结构看WebError是一个纯数据载体immutable payload构造时注入 page、error、location 三要素运行期不再变化。它同时实现了api.WebError类型接口由 types.d.ts 生成保证四语言 API 的语义一致。实战把 weberror 用于测试与监控场景一断言页面异常行为测试本身可能需要验证页面在某操作下会抛出某个异常例如验证错误处理 UI 触发条件。仓库测试 browsercontext-events.spec.ts 展示了标准写法——用Promise.all并发等待事件与触发动作避免竞态test(weberror event should work, async ({ page }) { const [webError] await Promise.all([ page.context().waitForEvent(weberror), page.setContent(scriptthrow new Error(boom)/script), ]); expect(webError.page()).toBe(page); expect(webError.error().stack).toContain(boom); });注意webError.error().stack包含boom——这验证了error()返回的确实是带堆栈的Error对象而不仅仅是 message 字符串。场景二全局异常监控在一个测试文件或 CI 流水线中为每个BrowserContext挂一个监听器把异常连同location().url一起记录可以快速定位是哪个脚本文件的第几行在什么情况下崩了test.use({}); test.beforeEach(({ context }) { context.on(weberror, webError { const { url, line, column } webError.location(); console.warn([weberror] ${webError.error().message} ${url}:${line}:${column}); }); });由于weberror是 context 级事件这里一处订阅即可覆盖该 context 的全部页面无需为每个page单独注册。参考与验证路径内容仓库路径WebError API 文档docs/src/api/class-weberror.mdWebError 客户端类packages/playwright-core/src/client/webError.tspageError 事件接线双派发packages/playwright-core/src/client/browserContext.ts事件名映射weberrorpackages/playwright-core/src/client/events.ts协议事件定义SerializedErrorpackages/protocol/spec/browserContext.yml行为测试含 location 用例tests/library/browsercontext-events.spec.ts总结WebError虽然 API 面很小error()、page()、location()三个方法但配合 context 级weberror事件与SerializedError协议传输机制构成了 Playwright 对页面未处理异常的完整观测入口。使用时记住三点事件挂在BrowserContext上、location().line是 0-based、column值跨浏览器不保证一致。【免费下载链接】playwrightPlaywright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表