MST

星途 面试题库

面试题:JavaScript 错误边界与全局错误处理优化

在大型 JavaScript Web 应用中,错误边界对于防止错误扩散至关重要。请说明如何实现一个自定义的错误边界组件(假设在类似 React 的框架环境下),并解释如何结合全局错误处理机制,使得应用在捕获到未处理错误时,不仅能记录错误信息到服务器,还能优雅地回退到一个稳定状态,同时尽量不影响用户体验。请提供具体的代码示例和思路。
18.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

实现自定义错误边界组件思路

  1. 定义错误边界组件:在 React 中,错误边界是一个 class 组件,它可以捕获子组件树中任何位置抛出的 JavaScript 错误,并记录错误信息,同时渲染回退 UI。
  2. 生命周期方法:使用 componentDidCatch 生命周期方法来捕获错误。此方法在后代组件抛出错误后会被调用。
  3. 错误处理与上报:在 componentDidCatch 中,将错误信息发送到服务器进行记录,例如通过 AJAX 请求。
  4. 回退 UI:返回一个稳定的 UI,以告知用户发生了错误,而不是让整个应用崩溃。

结合全局错误处理机制思路

  1. 全局错误监听:除了错误边界,使用 window.onerror 来捕获全局未处理的错误,确保所有错误都能被记录。
  2. 统一处理:在 window.onerror 中,同样将错误信息发送到服务器,并尝试恢复应用到一个稳定状态,例如显示一个全局的错误提示。

代码示例

import React, { Component } from 'react';

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

  componentDidCatch(error, errorInfo) {
    // 记录错误到服务器
    fetch('/api/log-error', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ error, errorInfo })
    });

    this.setState({ hasError: true });
  }

  render() {
    if (this.state.hasError) {
      // 回退 UI
      return (
        <div>
          <h1>发生错误!</h1>
          <p>我们已经记录了这个问题,会尽快修复。</p>
        </div>
      );
    }
    return this.props.children;
  }
}

// 全局错误处理
window.onerror = function(message, source, lineno, colno, error) {
  fetch('/api/log-error', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ message, source, lineno, colno, error })
  });

  // 显示全局错误提示
  const globalErrorElement = document.createElement('div');
  globalErrorElement.innerHTML = `
    <h1>全局错误!</h1>
    <p>${message}</p>
  `;
  document.body.appendChild(globalErrorElement);

  return true; // 阻止默认的错误处理行为
};

// 使用错误边界
function App() {
  return (
    <ErrorBoundary>
      <div>
        {/* 可能抛出错误的子组件 */}
      </div>
    </ErrorBoundary>
  );
}

export default App;