Featured image of post 具有錯誤邊界的強大前端異常管理Featured image of post 具有錯誤邊界的強大前端異常管理

具有錯誤邊界的強大前端異常管理

在運行時失敗時實現回退渲染狀態,並將崩潰詳細資訊清楚地記錄到日誌 Webhook 中。

為什麼誤差邊界很重要

在 React 應用程式中,元件中一個未捕獲的 JavaScript 錯誤可能會導致整個 UI 崩潰。在錯誤邊界之前,這表示使用者會看到一個白屏,沒有任何錯誤提示。錯誤邊界是 React 元件,可以捕捉子元件樹中任何位置的 JavaScript 錯誤,並呈現後備 UI,而不是崩潰。

實現誤差邊界

錯誤邊界是實作靜態生命週期方法 getDerivedStateFromErrorcomponentDidCatch 之一或兩者的類別元件:

import React, { Component, ErrorInfo, ReactNode } from "react";

interface Props {
  children: ReactNode;
  fallback?: ReactNode;
}

interface State {
  hasError: boolean;
  error: Error | null;
}

class ErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { hasError: false, error: null };
  }

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

  componentDidCatch(error: Error, info: ErrorInfo) {
    console.error("Error caught:", error, info.componentStack);
    // Send to logging service
    logErrorToService(error, info);
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback || <DefaultFallback error={this.state.error} />;
    }
    return this.props.children;
  }
}

後備 UI 設計

良好的後備 UI 提供恢復選項並減少使用者的挫折感:

function DefaultFallback({ error }: { error: Error | null }) {
  return (
    <div role="alert" className="error-boundary-fallback">
      <h2>Something went wrong</h2>
      <p>We encountered an unexpected error. Please try refreshing the page.</p>
      <button onClick={() => window.location.reload()}>
        Refresh Page
      </button>
      {process.env.NODE_ENV === "development" && (
        <pre>{error?.message}</pre>
      )}
    </div>
  );
}

與日誌服務整合 (Sentry)

錯誤邊界與 Sentry 等錯誤監控工具自然整合:

import * as Sentry from "@sentry/react";

class SentryErrorBoundary extends Component<Props, State> {
  componentDidCatch(error: Error, info: ErrorInfo) {
    Sentry.withScope((scope) => {
      scope.setExtras({ componentStack: info.componentStack });
      Sentry.captureException(error);
    });
  }
}

Sentry 還提供了一個內建的錯誤邊界包裝器:

<Sentry.ErrorBoundary fallback={<ErrorFallback />}>
  <App />
</Sentry.ErrorBoundary>

邊界放置策略

錯誤邊界的策略佈局至關重要:

App
├── ErrorBoundary (global fallback)
│   ├── Layout
│   │   ├── Header
│   │   ├── ErrorBoundary (content area fallback)
│   │   │   ├── MainContent
│   │   │   └── DataTable
│   │   └── Footer
│   └── ErrorBoundary (sidebar fallback)
│       └── SidebarWidget

指南:

  • 獨立包裝每個主要部分(側邊欄、主要內容、模式)
  • 僅將根邊界用作最後的手段
  • 將邊界放置在故障可恢復的特徵邊界處
  • 允許 UI 的正常部分保持功能

錯誤恢復模式

除了顯示回退之外,錯誤邊界還可以提供恢復:

class RecoverableBoundary extends Component {
  state = { hasError: false, error: null };

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

  handleRetry = () => {
    this.setState({ hasError: false, error: null });
  };

  render() {
    if (this.state.hasError) {
      return (
        <div>
          <p>Error: {this.state.error?.message}</p>
          <button onClick={this.handleRetry}>Retry</button>
        </div>
      );
    }
    return this.props.children;
  }
}

限制

誤差邊界有需要理解的重要限制:

限制說明
事件處理程序onClick 等中的錯誤不會被捕獲 - 使用 try-catch
非同步程式碼setTimeoutPromise 錯誤未被捕獲
固態繼電器錯誤邊界不會捕獲伺服器端錯誤
自己的錯誤錯誤邊界無法捕獲其自身的錯誤
狀態突變並非旨在處理損壞的全域狀態

結論

錯誤邊界是生產 React 應用程式的重要組成部分。它們可以防止 UI 完全崩潰,提供優雅的降級,並與日誌記錄服務無縫整合。透過將戰略邊界放置與正確的錯誤日誌記錄和復原模式相結合,您可以建立能夠優雅地處理故障並為開發人員提供可操作診斷的應用程式。