Skip to content

错误捕获系统

系统架构

错误捕获系统由三个核心模块组成:

  • ErrorCaptureManager: 错误捕获管理器,负责统一管理和初始化
  • MainErrorCapturer: 主进程错误捕获器
  • RendererErrorCapturer: 渲染进程错误捕获器
Preview

配置项

resources/config/config.ini 中配置:

ini
# 是否启用渲染进程错误捕获
enableRendererErrorCapture = true

# 是否启用全局错误捕获(主进程)
enableGlobalErrorCapture = true

主进程错误捕获

捕获类型

主进程错误捕获器可以捕获以下类型的错误:

  1. 未捕获的异常 (uncaughtException)
  2. 未处理的 Promise 拒绝 (unhandledRejection)
  3. 警告信息 (warning)

实现原理

javascript
// 未捕获的异常
process.on('uncaughtException', (error, origin) => {
  logger.error('未捕获的异常:', { error, origin });
});

// 未处理的 Promise 拒绝
process.on('unhandledRejection', (reason, promise) => {
  logger.error('未处理的 Promise 拒绝:', { reason, promise });
});

// 进程警告
process.on('warning', (warning) => {
  logger.warn('进程警告:', warning);
});

错误处理流程

发生错误

捕获错误信息

记录到日志文件

触发错误展示页面(可选)

渲染进程错误捕获

捕获方式

渲染进程通过 IPC 通信将错误信息发送到主进程:

javascript
// 渲染进程 preload
window.addEventListener('error', (event) => {
  ipcRenderer.send('renderer-error', {
    message: event.error.message,
    stack: event.error.stack,
    // ...其他错误信息
  });
});

window.addEventListener('unhandledrejection', (event) => {
  ipcRenderer.send('renderer-promise-error', {
    reason: event.reason,
    // ...其他信息
  });
});

IPC 处理器

主进程注册 IPC 处理器接收渲染进程错误:

javascript
ipcMain.on('renderer-error', (event, errorInfo) => {
  logger.error('渲染进程错误:', errorInfo);
  // 可选:显示错误页面
});

ipcMain.on('renderer-promise-error', (event, errorInfo) => {
  logger.error('渲染进程 Promise 错误:', errorInfo);
});

使用方式

初始化

在主进程启动时自动初始化:

javascript
const ErrorCaptureManager = require('./capturer/error-capture-manager');

// 获取单例并初始化
const errorManager = ErrorCaptureManager.getInstance();
errorManager.initialize();

清理资源

在应用退出时清理:

javascript
app.on('before-quit', () => {
  const errorManager = ErrorCaptureManager.getInstance();
  errorManager.cleanup();
});

错误展示页面

当发生严重错误时,系统会加载错误展示页面 error.html,向用户友好地展示错误信息。

错误页面加载场景

  • 窗口加载失败
  • 网络连接错误
  • 资源加载超时
  • 其他无法恢复的错误

特殊说明

无法捕获的情况

以下情况下的错误可能无法被捕获:

  1. 崩溃前未能发送到主进程的渲染进程错误

    • 渲染进程崩溃速度过快
    • IPC 通信被中断
  2. 系统级别崩溃

    • 内存不足导致的进程终止
    • 操作系统强制终止
  3. 进程被强制终止

    • 任务管理器结束进程
    • 系统关机

最佳实践

  1. 及时处理异步错误

    javascript
    // 推荐:使用 try-catch
    try {
      await someAsyncOperation();
    } catch (error) {
      logger.error('操作失败:', error);
    }
  2. Promise 链式调用添加 catch

    javascript
    somePromise()
      .then((result) => handleResult(result))
      .catch((error) => logger.error('Promise 错误:', error));
  3. 重要操作添加错误边界

    javascript
    function criticalOperation() {
      try {
        // 关键操作
      } catch (error) {
        logger.error('关键操作失败:', error);
        // 降级处理
      }
    }

日志输出

所有捕获的错误都会被记录到日志文件中,日志位置:

  • 开发环境: 项目根目录/logs/YYYY-MM/YYYY-MM-DD.log
  • 生产环境: 应用安装目录/logs/YYYY-MM/YYYY-MM-DD.log

日志格式示例:

[2025-12-09 14:30:25.123] [Main][error] 未捕获的异常: {
  error: Error: Something went wrong
    at someFunction (main.js:123:45)
    ...
  origin: uncaughtException
}

相关文件

  • packages/main/src/capturer/error-capture-manager.js - 错误捕获管理器
  • packages/main/src/capturer/main-error-capturer.js - 主进程错误捕获器
  • packages/main/src/capturer/renderer-error-capturer.js - 渲染进程错误捕获器
  • packages/main/src/capturer/error-capturer-preload.js - 渲染进程 preload 脚本
  • packages/renderer/error.html - 错误展示页面

基于 MIT 许可发布