- 跨平台
- 移动开发
- 前端
【免费下载链接】Hippy
Hippy is designed to easily build cross-platform dynamic apps. 👏
Hippy 作为跨平台动态化方案,JS 侧运行时错误(未捕获异常与未处理的 Promise rejection)会直接影响业务稳定性。本文基于 Hippy 官方文档 docs/feature/feature2.0/exception.md,系统讲解如何通过监听uncaughtException与unhandledRejection事件完成错误捕获与上报,并结合仓库源码(C++ 层 VM 实现、官方 demo 与 webpack 配置)说明其底层原理与完整接入方式。读完本文,你将掌握在 Hippy 2.0+ 业务中搭建一套可落地的 JS 异常监控方案。
一、异常捕获能力总览
Hippy 在 JS 运行环境(Android V8、iOS JSCore、Hermes 等)之上提供了一套统一的事件机制,业务侧通过global.Hippy这个全局事件总线订阅异常事件。涉及两类核心事件:
| 事件名 | 触发场景 | 平台支持 |
|---|---|---|
uncaughtException | JS 代码中未被任何 try/catch 捕获的同步异常 | Android / iOS / 其他引擎均可 |
unhandledRejection | Promise 被 reject 且没有任何 reject 处理器 | 仅 iOS(JSCore,需 polyfill),Android(V8)暂不支持 |
global.Hippy是 Hippy 暴露给业务侧的标准全局对象,on()方法用于注册事件监听,与官方 demo 中的用法完全一致(参见 driver/js/examples/hippy-react-demo/src/main.js)。
二、捕获未处理异常:uncaughtException
对于 JS 代码中抛出的、没有被try/catch或 Promise 链处理掉的异常,Hippy 会在运行时将其封装为uncaughtException事件派发出去。业务侧只需要在入口处注册监听即可:
global.Hippy.on('uncaughtException', (...args) => { // 此处可以做错误上报 report('[uncaughtException]', ...args); });官方 demo 中给出了更贴近真实生产的用法,同时取err.stack与err.message用于定位问题:
// driver/js/examples/hippy-react-demo/src/main.js global.Hippy.on('uncaughtException', (err) => { console.error('uncaughtException error', err.stack, err.message); });底层实现原理
从源码结构看,uncaughtException事件并非纯 JS 层模拟,而是由 C++ 层 JS 引擎适配统一驱动:
- V8(Android):在 driver/js/src/js_driver_utils.cc 中,引擎初始化完成后通过
FunctionWrapper包装一个回调,调用V8VM::HandleException(scope->GetContext(), "uncaughtException", exception)将异常转发到事件系统,并通过AddUncaughtExceptionMessageListener注册监听器;随后从引擎 VM 取出UncaughtExceptionCallback,把异常描述与堆栈(description、stack)传给桥接层回调。 - JSH(其他 JSH 系引擎):同一文件 driver/js/src/js_driver_utils.cc 中执行完全一致的逻辑,调用
JSHVM::HandleException(...)。 - Hermes(iOS):在 driver/js/src/napi/hermes/hermes_ctx.cc 中,
HandleJsException同样以"uncaughtException"为事件名调用VM::HandleException,并携带description与stack回调。
也就是说,无论底层跑的是哪个 JS 引擎,Hippy 都会把“未捕获异常”归一化为统一的uncaughtException事件,业务侧监听逻辑与引擎无关,天然具备跨端一致性。
三、捕获未处理 Promise 拒绝:unhandledRejection
当某个 Promise 被reject且始终没有注册.catch()或then(onRejected)处理器时,即触发unhandledRejection事件:
global.Hippy.on('unhandledRejection', (reason) => { console.error('unhandledRejection', reason); });平台差异与注意事项
重要限制:当前只能通过 JS polyfill 的方式捕获 iOS(JSCore)Promise 的
unhandledRejection错误,Android(V8)暂不支持。
原因是 iOS 上 Promise 本身采用 polyfill 实现(非引擎原生 Promise),因此可以借助rejection-tracking机制在 JS 层追踪未处理的 rejection;而 Android V8 引擎的原生 Promise 目前无法通过该方式拦截。如果你的业务同时运行在双端,需要接受 Android 端该事件暂时收不到的现实,并在错误监控平台上做好区分标记。
四、iOS 接入 rejection-tracking polyfill(完整实操)
针对 iOS,Hippy 提供了官方 polyfill 包@hippy/rejection-tracking-polyfill,接入分为三步。
1. 安装依赖
npm install -D @hippy/rejection-tracking-polyfill最低支持版本
2.14.1(即 Hippy 2.14.1 及以上版本才支持该 polyfill 方案)。
由于rejection-tracking有一定性能损耗,官方文档明确建议仅在业务确有需要时才引入该插件,避免无谓的开销。
2. 注入 polyfill(两种方式任选)
方式一:在 webpack 配置的 entry 中注入
将 polyfill 置于业务入口之前,保证它在业务代码执行前完成对 Promise 的包装:
// 可以在 iOS webpack config 配置 module.exports = { entry: { // 注入 polyfill 代码 index: ['@hippy/rejection-tracking-polyfill', 'dist/dev/index.js'] }, }官方 demo 的实际 webpack 配置与此一致,参见 driver/js/examples/hippy-react-demo/scripts/hippy-webpack.ios.js:
index: ['@hippy/rejection-tracking-polyfill', 'regenerator-runtime', path.resolve(pkg.main)],方式二:在业务代码入口直接 import
以 hippy-react 为例,在创建 Hippy 实例之前引入 polyfill:
// 也可以在业务代码里直接引入,以 hippy-react 举例 import { Hippy } from '@hippy/react'; import '@hippy/rejection-tracking-polyfill'; new Hippy({ appName: 'Demo', entryPage: App, }).start();两种方式等价,推荐在 iOS 专用 webpack 配置(如hippy-webpack.ios.js/hippy-webpack.hermes.ios.js)中通过 entry 注入,这样可以把 polyfill 的成本严格限定在 iOS 产物内,Android 包不受影响。
3. 监听错误
global.Hippy.on('unhandledRejection', (reason) => { console.error('unhandledRejection', reason); });五、在业务入口中组合完整监控方案
结合 Hippy 官方 demo(driver/js/examples/hippy-react-demo/src/main.js),一个完整的入口监控代码长这样:
import { Hippy } from '@hippy/react'; import App from './app'; global.Hippy.on('uncaughtException', (err) => { console.error('uncaughtException error', err.stack, err.message); }); // only supported in iOS temporarily global.Hippy.on('unhandledRejection', (reason) => { console.error('unhandledRejection reason', reason); }); new Hippy({ appName: 'Demo', entryPage: App, // set global bubbles, default is false bubbles: false, // set log output, default is false silent: false, }).start();同样地,hippy-vue 与 hippy-vue-next 的官方 demo(如 driver/js/examples/hippy-vue-demo/src/main-native.js、driver/js/examples/hippy-vue-next-demo/src/main-native.ts)也采用了相同的监听写法,说明这套异常捕获 API 对 hippy-react、hippy-vue、hippy-vue-next 各框架统一适用。
六、实践建议与注意事项
- 尽早注册监听:
global.Hippy.on('uncaughtException', ...)应在入口文件顶部、业务初始化之前完成注册,避免漏掉启动阶段的异常。 - 监控与上报分离:监听回调内只做轻量的错误信息采集与上报(如拼接
stack、message、平台标识、版本号),不要把重逻辑放进回调,防止二次异常。 - 明确平台边界:
unhandledRejection当前仅 iOS 可用且依赖 polyfill,Android(V8)暂不支持;同时该 polyfill 存在性能损耗,应结合业务诉求决定是否启用,而非默认全量接入。 - 多引擎归一化:由于 C++ 层(V8 / JSH / Hermes)统一以
uncaughtException事件名派发异常,业务监听代码无需按引擎分叉,便于长期维护。 - 配合日志模块:异常捕获可与 Hippy 的日志能力(参见 docs/feature/feature2.0/console.md)配合使用,将错误堆栈同步输出到日志通道,方便线上问题排查。
通过以上方案,你可以在 Hippy 2.0+ 业务中建立起覆盖同步异常与 Promise 拒绝的跨端错误监控体系,将线上 JS 错误收敛到统一的上报通道。
- 跨平台
- 移动开发
- 前端
【免费下载链接】Hippy
Hippy is designed to easily build cross-platform dynamic apps. 👏
相关推荐
一键获取智慧教育资源:免费电子课本下载工具终极指南
一键获取智慧教育资源:免费电子课本下载工具终极指南 在数字化教育时代, 国家中小学智慧教育平台 为全国师生提供了丰富的电子教材资源。然而,如何高效地获取这些宝贵
网页爬虫教育VIA键盘自定义工具完整指南:3步打造你的专属键盘
VIA键盘自定义工具完整指南:3步打造你的专属键盘 还在为键盘按键不顺手而烦恼吗?想要让键盘真正成为你的专属工具吗?今天我要为你介绍一款完全免费的开源神器——V
如何永久保存微信聊天记录:WeChatMsg完整备份与导出终极指南
如何永久保存微信聊天记录:WeChatMsg完整备份与导出终极指南 你是否曾担心那些珍贵的微信对话会随着时间流逝而消失?与亲友的重要对话、工作群里的关键信息、学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考