不能用 try-catch 全量拦截原生底层进程错误,因其属操作系统级异常,不触发 js 异常机制;正确做法是分层治理:ipc 调用包裹 async try-catch、监听子进程 exit/error 事件、原生模块主动透传结构化错误,并统一注入 callid 与上下文实现可追溯审计。

不能用 try-catch 全量拦截跨端桌面应用中“原生底层进程”的异步核心抛错行为——这不是设计目标,也不具备可行性。
try-catch 本身不作用于原生进程错误
原生底层进程(如 Electron 中的 Node.js 子进程、Rust 编写的本地服务、C++ 扩展模块、系统级调用 spawn/exec)发生的崩溃、段错误、SIGSEGV、资源耗尽等,属于操作系统或运行时层面的异常,不会以 JavaScript 异常对象形式抛出,因此无法被 JS 层的 try-catch 捕获。
- Node.js 的
child_process中子进程崩溃只会触发exit或error事件,不是 throw 行为 - Rust/FFI 模块 panic 或 abort 不经过 V8 异常机制,直接终止线程或进程
- Electron 主进程崩溃(如 native addon crash)会导致整个主进程退出,JS 无机会执行任何 catch
真正可审计的“异步核心抛错”需分层治理
所谓“全量拦截并审计”,应理解为:在 JS 与原生边界处建立可观测、可透传、可归因的错误通道,而非幻想用 try-catch 包裹 C++ 代码。
-
通信层兜底:所有 IPC 调用(
ipcRenderer.invoke/ipcMain.handle)必须包裹 async try-catch,并在 catch 中记录 method、args、traceId、原生返回码(如 errno)、错误类型(timeout / reject / native_error) -
子进程生命周期监听:对
spawn()启动的进程,监听error(启动失败)、exit(非零码退出)、close(正常结束),将 exitCode、signal、stderr 输出统一格式化后上报审计中心 -
原生模块错误桥接:若使用 NAPI/Rust/FFI,要求原生侧主动将关键错误转为结构化 JSON 字符串,通过回调或事件发送到 JS 层(例如:
onError({ code: 'NATIVE_OOM', message: 'malloc failed', pid: 1234 })),再由 JS 统一记录
审计落地的关键动作
审计不是日志堆砌,而是让错误可追溯、可分类、可联动:
- 每个原生调用入口注入唯一
callId和上下文(用户ID、窗口ID、操作场景),确保错误能反向关联前端行为 - 错误上报必须包含:时间戳、进程角色(renderer/main)、平台(win/mac/linux)、架构(x64/arm64)、原生模块版本、错误原始 payload
- 建立错误码字典映射表(如
ERR_NATIVE_FILE_LOCKED → 0x1002),避免依赖模糊字符串匹配 - 对高频错误(如
ENOSPC、EACCES)配置自动告警和自助恢复提示(“磁盘空间不足,请清理缓存”)
不要混淆“捕获”和“观测”
try-catch 是同步错误的局部处理工具;而跨端原生错误审计,本质是分布式系统可观测性问题。它依赖:
- IPC 协议层的错误语义约定(比如响应体始终含
{ ok: false, code, message, detail }) - 进程管理器(如 pm2-like 进程守护)对崩溃的重启与快照捕获
- 符号化堆栈支持(Sourcemap + native symbol server)还原 C++ 崩溃点
- 全局 unhandledrejection + error 监听作为最后防线,捕获 JS 层漏掉的 Promise 错误或未处理异常











