LogRocket 错误追踪 #

什么是错误追踪? #

错误追踪是捕获、记录和分析应用程序中错误的过程。LogRocket 提供了完整的错误追踪解决方案,帮助你快速定位和修复问题。

text
┌─────────────────────────────────────────────────────────────┐
│                    错误追踪的价值                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  传统方式:                                                  │
│  用户报告问题 → 开发者尝试复现 → 查看日志 → 猜测原因        │
│  问题:                                                     │
│  ❌ 依赖用户反馈                                            │
│  ❌ 信息不完整                                              │
│  ❌ 难以复现                                                │
│  ❌ 修复周期长                                              │
│                                                             │
│  LogRocket 方式:                                           │
│  错误自动捕获 → 完整上下文 → 会话回放 → 快速定位            │
│  优势:                                                     │
│  ✅ 自动捕获所有错误                                        │
│  ✅ 完整的错误上下文                                        │
│  ✅ 关联用户操作                                            │
│  ✅ 快速定位和修复                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

错误类型 #

JavaScript 错误 #

text
┌─────────────────────────────────────────────────────────────┐
│                    JavaScript 错误类型                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. SyntaxError(语法错误)                                 │
│     - 代码解析错误                                          │
│     - 通常在开发阶段发现                                    │
│                                                             │
│  2. ReferenceError(引用错误)                              │
│     - 访问未定义的变量                                      │
│     - 示例:Cannot read property 'x' of undefined           │
│                                                             │
│  3. TypeError(类型错误)                                   │
│     - 类型不匹配的操作                                      │
│     - 示例:undefined is not a function                     │
│                                                             │
│  4. RangeError(范围错误)                                  │
│     - 值超出有效范围                                        │
│     - 示例:Maximum call stack size exceeded                │
│                                                             │
│  5. URIError(URI 错误)                                    │
│     - URI 编码/解码错误                                     │
│                                                             │
│  6. EvalError(Eval 错误)                                  │
│     - eval() 相关错误                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Promise 拒绝 #

javascript
// 未捕获的 Promise 拒绝
fetch('/api/data')
  .then(response => response.json())
  .then(data => {
    console.log(data.nonexistent.property);
  });
// 如果 fetch 失败或数据结构不符预期,会产生未捕获的拒绝

资源加载错误 #

html
<!-- 图片加载失败 -->
<img src="nonexistent.jpg" onerror="handleError()">

<!-- 脚本加载失败 -->
<script src="missing-script.js"></script>

<!-- 样式表加载失败 -->
<link rel="stylesheet" href="missing-styles.css">

控制台错误 #

javascript
console.error('Critical error occurred');
console.warn('Warning: deprecated API used');

自动错误捕获 #

LogRocket 自动捕获以下错误:

text
┌─────────────────────────────────────────────────────────────┐
│                    自动捕获的错误                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ✅ 未捕获的 JavaScript 错误                                │
│     - window.onerror                                        │
│     - window.addEventListener('error')                      │
│                                                             │
│  ✅ 未处理的 Promise 拒绝                                   │
│     - window.onunhandledrejection                           │
│     - window.addEventListener('unhandledrejection')         │
│                                                             │
│  ✅ 控制台错误                                              │
│     - console.error()                                       │
│     - console.warn()                                        │
│                                                             │
│  ✅ 网络请求错误                                            │
│     - XHR 错误                                              │
│     - Fetch 错误                                            │
│                                                             │
│  ✅ 资源加载错误                                            │
│     - 图片加载失败                                          │
│     - 脚本加载失败                                          │
│     - 样式表加载失败                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

手动捕获错误 #

captureException #

javascript
import LogRocket from 'logrocket';

try {
  riskyOperation();
} catch (error) {
  LogRocket.captureException(error);
}

带额外信息 #

javascript
try {
  processOrder(orderData);
} catch (error) {
  LogRocket.captureException(error, {
    extra: {
      orderId: orderData.id,
      userId: orderData.userId,
      items: orderData.items
    },
    tags: {
      feature: 'checkout',
      severity: 'high'
    }
  });
}

捕获自定义错误 #

javascript
class ValidationError extends Error {
  constructor(message, field) {
    super(message);
    this.name = 'ValidationError';
    this.field = field;
  }
}

function validateForm(data) {
  if (!data.email) {
    const error = new ValidationError('Email is required', 'email');
    LogRocket.captureException(error, {
      extra: {
        formData: data,
        field: 'email'
      }
    });
    throw error;
  }
}

错误上下文 #

LogRocket 提供的上下文 #

text
┌─────────────────────────────────────────────────────────────┐
│                    错误上下文信息                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  环境信息:                                                  │
│  - 浏览器类型和版本                                         │
│  - 操作系统                                                 │
│  - 设备类型                                                 │
│  - 屏幕分辨率                                               │
│  - 语言设置                                                 │
│                                                             │
│  用户信息:                                                  │
│  - 用户 ID                                                  │
│  - 用户属性                                                 │
│  - 会话 ID                                                  │
│                                                             │
│  页面信息:                                                  │
│  - 当前 URL                                                 │
│  - 页面标题                                                 │
│  - Referrer                                                 │
│                                                             │
│  技术信息:                                                  │
│  - 错误堆栈                                                 │
│  - 源码位置                                                 │
│  - 网络请求                                                 │
│  - 控制台日志                                               │
│  - Redux/Vuex 状态                                         │
│                                                             │
│  操作历史:                                                  │
│  - 面包屑                                                   │
│  - 用户交互                                                 │
│  - 页面导航                                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

错误详情示例 #

javascript
{
  "error": {
    "type": "TypeError",
    "message": "Cannot read property 'id' of undefined",
    "stacktrace": [
      {
        "filename": "https://example.com/static/js/main.js",
        "lineno": 123,
        "colno": 45,
        "function": "getUserData"
      }
    ]
  },
  "context": {
    "user": {
      "id": "user-123",
      "email": "john@example.com"
    },
    "browser": {
      "name": "Chrome",
      "version": "120.0"
    },
    "os": {
      "name": "Windows",
      "version": "10"
    },
    "url": "https://example.com/dashboard",
    "breadcrumbs": [
      { "type": "navigation", "message": "Navigate to /dashboard" },
      { "type": "http", "message": "GET /api/users" }
    ],
    "networkRequests": [
      { "url": "/api/users", "status": 200, "duration": 245 }
    ]
  }
}

错误分组 #

自动分组规则 #

text
┌─────────────────────────────────────────────────────────────┐
│                    错误分组规则                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  LogRocket 自动将相似错误分组:                              │
│                                                             │
│  分组依据:                                                  │
│  1. 错误类型(TypeError, ReferenceError...)                │
│  2. 错误消息模式                                            │
│  3. 堆栈指纹                                                │
│  4. 源文件位置                                              │
│                                                             │
│  示例:                                                     │
│                                                             │
│  Issue #1234: TypeError: Cannot read property 'id'          │
│  ├── 发生次数: 1,234 次                                     │
│  ├── 影响用户: 567 人                                       │
│  ├── 首次发生: 2024-01-15 10:30:00                         │
│  └── 最后发生: 2024-01-20 15:45:00                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

自定义分组 #

javascript
LogRocket.captureException(error, {
  fingerprint: ['{{ default }}', 'checkout-flow'],
  extra: {
    customGroupingKey: 'checkout-error'
  }
});

Source Map 配置 #

为什么需要 Source Map? #

text
┌─────────────────────────────────────────────────────────────┐
│                    Source Map 的作用                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  问题:生产环境代码被压缩和混淆                              │
│                                                             │
│  压缩后的错误堆栈:                                          │
│  TypeError: Cannot read property 'id' of undefined          │
│    at a (main.min.js:1:2345)                               │
│    at b (main.min.js:1:3456)                               │
│    at c (main.min.js:1:4567)                               │
│                                                             │
│  使用 Source Map 后:                                        │
│  TypeError: Cannot read property 'id' of undefined          │
│    at getUserData (user.js:45:12)                          │
│    at fetchUsers (api.js:123:8)                            │
│    at componentDidMount (UserList.jsx:34:5)                │
│                                                             │
│  优势:                                                     │
│  ✅ 看到原始文件名                                          │
│  ✅ 看到原始行号和列号                                      │
│  ✅ 看到原始函数名                                          │
│  ✅ 快速定位问题                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

上传 Source Map #

使用 CLI #

bash
npm install -g @logrocket/cli

logrocket upload <app-id> <path-to-sourcemaps> \
  --release <version> \
  --url-prefix <url-prefix>

使用 Webpack 插件 #

javascript
const LogRocketSourceMapPlugin = require('@logrocket/webpack-plugin');

module.exports = {
  plugins: [
    new LogRocketSourceMapPlugin({
      appID: 'your-app-id',
      release: process.env.npm_package_version,
      publicPath: 'https://example.com/static/js/'
    })
  ]
};

使用 CI/CD #

yaml
# GitHub Actions 示例
- name: Upload Source Maps to LogRocket
  run: |
    npm install -g @logrocket/cli
    logrocket upload your-app-id ./dist/static/js \
      --release ${{ env.VERSION }} \
      --url-prefix https://example.com/static/js/
  env:
    LOGROCKET_API_KEY: ${{ secrets.LOGROCKET_API_KEY }}

Source Map 最佳实践 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Source Map 最佳实践                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 版本管理                                                │
│     - 每次发布使用唯一版本号                                │
│     - Source Map 与版本对应                                 │
│                                                             │
│  2. 自动化上传                                              │
│     - 在 CI/CD 流程中自动上传                               │
│     - 确保与部署同步                                        │
│                                                             │
│  3. URL 前缀                                                │
│     - 正确配置 URL 前缀                                     │
│     - 确保 Source Map 可被正确匹配                          │
│                                                             │
│  4. 安全考虑                                                │
│     - 不要将 Source Map 部署到生产环境                      │
│     - 只上传到 LogRocket                                    │
│     - 保护 API Key                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

错误分析 #

错误仪表板 #

text
┌─────────────────────────────────────────────────────────────┐
│                    错误仪表板                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              错误概览                                │   │
│  │                                                     │   │
│  │   今日错误: 1,234    影响用户: 567    新增: 5       │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              错误趋势                                │   │
│  │                                                     │   │
│  │   [错误数量趋势图]                                   │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              错误列表                                │   │
│  │                                                     │   │
│  │   错误类型        消息              次数    用户     │   │
│  │   TypeError    Cannot read...      567     123      │   │
│  │   ReferenceError x is not...       234     89       │   │
│  │   NetworkError  Failed to...       123     45       │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

错误详情分析 #

text
┌─────────────────────────────────────────────────────────────┐
│                    错误详情页面                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  错误信息:                                                  │
│  - 错误类型                                                 │
│  - 错误消息                                                 │
│  - 堆栈跟踪                                                 │
│                                                             │
│  统计信息:                                                  │
│  - 发生次数                                                 │
│  - 影响用户数                                               │
│  - 首次/最后发生时间                                        │
│                                                             │
│  分布信息:                                                  │
│  - 浏览器分布                                               │
│  - 操作系统分布                                             │
│  - 页面分布                                                 │
│  - 版本分布                                                 │
│                                                             │
│  相关会话:                                                  │
│  - 最近发生的会话列表                                       │
│  - 点击查看会话回放                                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

错误过滤 #

text
┌─────────────────────────────────────────────────────────────┐
│                    错误过滤                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  按类型过滤:                                                │
│  - TypeError                                                │
│  - ReferenceError                                           │
│  - NetworkError                                             │
│                                                             │
│  按环境过滤:                                                │
│  - 浏览器                                                   │
│  - 操作系统                                                 │
│  - 设备类型                                                 │
│                                                             │
│  按时间过滤:                                                │
│  - 最近 1 小时                                              │
│  - 最近 24 小时                                             │
│  - 最近 7 天                                                │
│  - 自定义范围                                               │
│                                                             │
│  按版本过滤:                                                │
│  - 特定版本                                                 │
│  - 版本范围                                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

错误告警 #

配置告警规则 #

javascript
// 在 LogRocket 控制台配置告警

// 示例告警规则
{
  "name": "高优先级错误告警",
  "conditions": {
    "errorType": "TypeError",
    "threshold": 10,
    "timeWindow": "1h",
    "affectedUsers": 5
  },
  "actions": [
    {
      "type": "email",
      "recipients": ["dev-team@example.com"]
    },
    {
      "type": "slack",
      "channel": "#alerts"
    }
  ]
}

告警类型 #

text
┌─────────────────────────────────────────────────────────────┐
│                    告警类型                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 错误频率告警                                            │
│     - 错误次数超过阈值                                      │
│     - 影响用户数超过阈值                                    │
│                                                             │
│  2. 新错误告警                                              │
│     - 首次出现的错误                                        │
│     - 新版本引入的错误                                      │
│                                                             │
│  3. 错误回归告警                                            │
│     - 已解决的错误再次出现                                  │
│                                                             │
│  4. 趋势告警                                                │
│     - 错误率持续上升                                        │
│     - 与上一周期对比                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

错误处理最佳实践 #

1. 全局错误处理 #

javascript
// JavaScript 错误
window.onerror = function(message, source, lineno, colno, error) {
  LogRocket.captureException(error || new Error(message), {
    extra: {
      source: source,
      lineno: lineno,
      colno: colno
    }
  });
  return false;
};

// Promise 拒绝
window.addEventListener('unhandledrejection', function(event) {
  LogRocket.captureException(event.reason, {
    extra: {
      type: 'unhandledrejection'
    }
  });
});

// 资源加载错误
window.addEventListener('error', function(event) {
  if (event.target !== window) {
    LogRocket.captureException(new Error('Resource load error'), {
      extra: {
        tagName: event.target.tagName,
        src: event.target.src || event.target.href
      }
    });
  }
}, true);

2. React 错误边界 #

javascript
import React from 'react';
import LogRocket from 'logrocket';

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    LogRocket.captureException(error, {
      extra: {
        componentStack: errorInfo.componentStack,
        props: this.props
      },
      tags: {
        feature: 'react-error-boundary'
      }
    });
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

export default ErrorBoundary;

3. API 错误处理 #

javascript
async function fetchWithTracking(url, options = {}) {
  try {
    const response = await fetch(url, options);
    
    if (!response.ok) {
      const error = new Error(`HTTP ${response.status}: ${response.statusText}`);
      LogRocket.captureException(error, {
        extra: {
          url: url,
          method: options.method || 'GET',
          status: response.status,
          statusText: response.statusText
        },
        tags: {
          type: 'api-error'
        }
      });
      throw error;
    }
    
    return response;
  } catch (error) {
    LogRocket.captureException(error, {
      extra: {
        url: url,
        method: options.method || 'GET'
      },
      tags: {
        type: 'network-error'
      }
    });
    throw error;
  }
}

4. 表单验证错误 #

javascript
function validateForm(formData) {
  const errors = [];
  
  if (!formData.email) {
    const error = new Error('Email is required');
    LogRocket.captureException(error, {
      extra: {
        field: 'email',
        formId: 'registration-form'
      },
      tags: {
        type: 'validation-error'
      },
      level: 'warning'
    });
    errors.push({ field: 'email', message: 'Email is required' });
  }
  
  if (!formData.password || formData.password.length < 8) {
    const error = new Error('Password must be at least 8 characters');
    LogRocket.captureException(error, {
      extra: {
        field: 'password',
        formId: 'registration-form'
      },
      tags: {
        type: 'validation-error'
      },
      level: 'warning'
    });
    errors.push({ field: 'password', message: 'Password must be at least 8 characters' });
  }
  
  return errors;
}

错误解决流程 #

text
┌─────────────────────────────────────────────────────────────┐
│                    错误解决流程                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Step 1: 收到错误告警                                       │
│          ↓                                                  │
│  Step 2: 查看错误详情                                       │
│          - 错误类型和消息                                   │
│          - 堆栈跟踪                                         │
│          - 影响范围                                         │
│          ↓                                                  │
│  Step 3: 分析错误上下文                                     │
│          - 用户信息                                         │
│          - 浏览器/设备                                      │
│          - 操作历史                                         │
│          ↓                                                  │
│  Step 4: 查看会话回放                                       │
│          - 观看错误发生过程                                 │
│          - 理解用户操作                                     │
│          ↓                                                  │
│  Step 5: 定位问题根因                                       │
│          - 分析代码                                         │
│          - 检查数据                                         │
│          ↓                                                  │
│  Step 6: 修复问题                                           │
│          - 编写修复代码                                     │
│          - 编写测试                                         │
│          ↓                                                  │
│  Step 7: 验证修复                                           │
│          - 部署修复                                         │
│          - 监控错误是否消失                                 │
│          ↓                                                  │
│  Step 8: 标记错误已解决                                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

下一步 #

现在你已经掌握了错误追踪的使用方法,接下来学习 高级功能 了解 LogRocket 的更多高级特性!

最后更新:2026-03-29