阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 错误监控方案

错误监控方案

作者:陈川 阅读数:32187人阅读 分类: 前端综合

工程化规范的必要性

前端项目规模扩大后,代码复杂度呈指数级增长。缺乏统一规范的代码库会迅速演变成难以维护的"屎山",不同开发者编写的代码风格各异,错误处理方式五花八门。工程化规范通过约束编码风格、统一错误处理机制、制定提交规范等手段,显著提升代码可维护性和团队协作效率。

典型问题场景:

  • 开发者A使用try-catch处理异步错误
  • 开发者B采用.catch处理Promise错误
  • 开发者C直接忽略错误处理
  • 同个项目出现4种不同的缩进风格
// 反例:混合的错误处理方式
function fetchData() {
  try {
    axios.get('/api').then(res => {
      // 业务逻辑
    }).catch(e => console.log(e)) // Promise风格
  } catch (e) { // try-catch风格
    alert('请求失败')
  }
}

错误监控体系架构

完整的错误监控方案包含三个层次:

  1. 采集层:覆盖运行时错误、资源加载错误、API请求错误、控制台错误等
  2. 传输层:区分生产/开发环境,采用不同的上报策略
  3. 分析层:错误聚合、源映射解析、影响用户分析
interface ErrorReport {
  timestamp: number;
  message: string;
  stack?: string;
  componentStack?: string; // React错误边界
  userAgent: string;
  location: string;
  customData?: Record<string, any>;
}

代码规范实施策略

ESLint配置进阶

基础规则集扩展需要结合项目技术栈:

// .eslintrc.js
module.exports = {
  extends: [
    'airbnb',
    'plugin:react-hooks/recommended',
    'plugin:@typescript-eslint/recommended'
  ],
  rules: {
    'no-console': ['error', { allow: ['warn', 'error'] }],
    'react/jsx-uses-react': 'off',
    'react/react-in-jsx-scope': 'off',
    '@typescript-eslint/no-floating-promises': 'error'
  }
}

关键规则配置:

  • no-floating-promises 强制处理Promise拒绝
  • require-await 防止无意义的async声明
  • no-misused-promises 避免Promise误用

Git Hooks集成

通过husky实现提交时自动校验:

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

错误分类与捕获方案

同步错误捕获

基础try-catch的局限性:

  • 无法捕获语法错误
  • 异步代码中的错误会逃逸
  • 性能影响微乎其微(约0.01ms/次)
// 典型误用案例
try {
  setTimeout(() => {
    throw new Error('异步错误'); // 无法被捕获
  }, 100);
} catch (e) {
  console.log('不会执行');
}

异步错误处理

现代前端项目的异步场景处理方案:

// Promise统一错误处理
const safeFetch = async (url: string) => {
  try {
    const resp = await fetch(url);
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
    return await resp.json();
  } catch (error) {
    // 统一上报逻辑
    reportError(error);
    // 返回安全值或重新抛出
    return null;
  }
};

// React Suspense边界
<ErrorBoundary fallback={<ErrorPage />}>
  <Suspense fallback={<Loader />}>
    <AsyncComponent />
  </Suspense>
</ErrorBoundary>

生产环境错误上报

性能优化的上报策略

  1. 节流上报:相同错误5分钟内不上报重复实例
  2. 队列批量上报:收集错误后统一发送
  3. 本地缓存:网络不可用时暂存IndexedDB
class ErrorTracker {
  constructor() {
    this.queue = [];
    this.debounceTimer = null;
    this.MAX_RETRY = 3;
  }

  report(error) {
    if (this.shouldFilter(error)) return;
    
    this.queue.push(error);
    clearTimeout(this.debounceTimer);
    this.debounceTimer = setTimeout(() => this.flush(), 5000);
  }

  async flush() {
    if (!navigator.onLine) {
      await this.saveToIDB(this.queue);
      return;
    }
    
    try {
      await sendBeacon('/api/errors', { errors: this.queue });
      this.queue = [];
    } catch (e) {
      if (this.retryCount < this.MAX_RETRY) {
        setTimeout(() => this.flush(), 2000);
        this.retryCount++;
      }
    }
  }
}

SourceMap映射方案

生产环境错误堆栈解析流程:

  1. 构建时生成sourcemap并上传至内部服务器
  2. 错误上报时记录版本号、构建ID
  3. 后台服务通过版本号匹配对应的sourcemap
  4. 使用mozila/source-map库进行反解析
# webpack配置示例
module.exports = {
  devtool: 'hidden-source-map',
  plugins: [
    new SourceMapUploadPlugin({
      url: 'https://internal.com/sourcemaps',
      exclude: [/node_modules/]
    })
  ]
}

错误分析维度设计

有效的错误分析应包含多维度数据:

  1. 用户维度

    • 设备类型
    • 操作系统版本
    • 网络环境
  2. 业务维度

    • 当前路由路径
    • 用户操作流程
    • 功能模块标识
  3. 技术维度

    • 错误类型(TypeError/ReferenceError等)
    • 调用堆栈深度
    • 依赖库版本
// 增强的错误上报数据示例
{
  "error": {
    "type": "TypeError",
    "message": "Cannot read property 'name' of null",
    "stack": "..."
  },
  "context": {
    "route": "/user/profile",
    "reduxState": {
      "auth": { "userId": 12345 }
    },
    "env": {
      "sdkVersion": "2.3.4",
      "browser": "Chrome/91.0.4472.124"
    },
    "breadcrumbs": [
      { "type": "click", "target": "#submit-btn", "timestamp": 1620000000000 },
      { "type": "api", "url": "/api/user", "status": 200 }
    ]
  }
}

监控系统集成实践

与现有系统对接

与Sentry集成的深度定制示例:

import * as Sentry from '@sentry/react';
import { Integrations } from '@sentry/tracing';

Sentry.init({
  dsn: 'https://example@sentry.io/123',
  release: process.env.REACT_APP_VERSION,
  integrations: [
    new Integrations.BrowserTracing({
      routingInstrumentation: Sentry.reactRouterV5Instrumentation(history)
    }),
  ],
  beforeSend(event) {
    // 过滤浏览器扩展错误
    if (event.stacktrace?.frames?.some(frame => 
      frame.filename?.includes('chrome-extension://'))) {
      return null;
    }
    return event;
  }
});

// 自定义标签
Sentry.configureScope(scope => {
  scope.setTag('environment', process.env.NODE_ENV);
});

性能监控联动

错误与性能数据关联分析:

// 使用PerformanceObserver监控长任务
const observer = new PerformanceObserver(list => {
  const entries = list.getEntries();
  entries.forEach(entry => {
    if (entry.duration > 100) {
      trackLongTask(entry);
    }
  });
});
observer.observe({ entryTypes: ['longtask'] });

// 资源加载监控
window.addEventListener('error', event => {
  if (event.target instanceof HTMLLinkElement || 
      event.target instanceof HTMLScriptElement) {
    reportResourceError({
      url: event.target.src || event.target.href,
      element: event.target.tagName
    });
  }
}, true);

持续优化机制

建立错误监控闭环流程:

  1. 分级报警

    • P0级错误(影响核心流程):实时短信通知
    • P1级错误(主要功能异常):每小时汇总邮件
    • P2级错误(边缘场景问题):每日报告
  2. 解决跟踪

    - [ ] #ERROR-123 购物车页面空指针异常
      - 影响用户: 2.3% (每日约1200人)
      - 首次出现: 2023-05-10
      - 相关提交: a1b2c3d (用户服务重构)
      - 修复负责人: @前端张伟
    
  3. 趋势分析

    • 建立错误率基线(如0.5%以下为正常)
    • 监控错误增长趋势
    • 版本发布前后错误率对比
// 错误率计算示例
function calculateErrorRate() {
  const totalPageViews = analytics.getPageViews();
  const errorCount = errorStore.getTotalErrors();
  return {
    rate: (errorCount / totalPageViews * 100).toFixed(2) + '%',
    trend: compareWithLastPeriod(errorCount)
  };
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

上一篇:性能监控方案

下一篇:自动化测试规范

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌