You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native应用全局错误捕获最优方案咨询

React Native 全局错误捕获最优方案

React Native的错误分JS层、Native原生层、组件渲染层三类,要实现全量捕获得分层处理,下面是落地性极强的方案:

1. JS 全局错误捕获

React Native 没有浏览器环境的window.onerror,官方推荐用ErrorUtils捕获JS层面的未处理错误,同时还要处理Promise未捕获的拒绝:

// 在项目入口文件(如index.js)配置
import { ErrorUtils } from 'react-native';

// 捕获同步/异步JS错误
const originalGlobalHandler = ErrorUtils.getGlobalHandler();
ErrorUtils.setGlobalHandler((error, isFatal) => {
  // 这里可做错误上报、本地日志存储
  console.error(`JS全局错误 ${isFatal ? '(致命)' : ''}:`, error);
  
  // 保留原有全局处理逻辑,避免吞掉错误
  if (originalGlobalHandler) {
    originalGlobalHandler(error, isFatal);
  }
});

// 捕获Promise未处理的拒绝
global.addEventListener('unhandledrejection', (event) => {
  console.error('Promise未捕获拒绝:', event.reason);
  // 可选:阻止默认行为,避免控制台重复输出
  event.preventDefault();
});

2. 组件渲染层错误捕获(Error Boundary)

针对组件渲染时抛出的错误(比如渲染null/undefined属性、数组越界),用React官方的Error Boundary组件包裹根组件或关键业务组件,避免单个组件崩溃导致整个App挂掉:

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

  static getDerivedStateFromError(error) {
    // 更新state,展示降级UI
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 上报错误详情
    console.error('组件渲染错误:', error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // 自定义降级UI,比如错误提示页
      return <Text>抱歉,页面出现错误,请稍后重试</Text>;
    }

    return this.props.children;
  }
}

// 在根组件中使用
export default function App() {
  return (
    <ErrorBoundary>
      {/* 你的App核心内容 */}
      <NavigationContainer>...</NavigationContainer>
    </ErrorBoundary>
  );
}

注意:Error Boundary 无法捕获异步错误、事件回调中的错误,这类错误需靠JS全局捕获处理。

3. Native 原生层错误捕获

原生层的崩溃(比如iOS的OC/Swift错误、Android的Java/Kotlin错误)需要在原生代码中配置:

iOS 端

在AppDelegate.m(或AppDelegate.swift)中添加全局异常捕获:

// AppDelegate.m
#import <UIKit/UIKit.h>
#import <React/RCTBridge.h>

void uncaughtExceptionHandler(NSException *exception) {
  // 收集错误信息:异常原因、调用栈
  NSString *errorMsg = [NSString stringWithFormat:@"Native崩溃: %@\n调用栈:\n%@", exception.reason, [exception callStackSymbols]];
  NSLog(@"%@", errorMsg);
  // 可写入本地日志或通过原生模块上报给JS层
}

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // 设置全局异常处理器
  NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
  // ...其他初始化代码
  return YES;
}

@end

Android 端

在MainApplication.java中配置全局异常处理器:

// MainApplication.java
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

public class MainApplication extends Application implements ReactApplication {

  @Override
  public void onCreate() {
    super.onCreate();
    // 设置全局未捕获异常处理器
    Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
      // 收集错误信息
      String errorMsg = "Native崩溃: " + throwable.getMessage() + "\n" + Log.getStackTraceString(throwable);
      Log.e("NativeError", errorMsg);
      // 可选:通过Toast提示用户,或写入本地文件
      new Handler(Looper.getMainLooper()).post(() -> {
        Toast.makeText(getApplicationContext(), "应用出现错误", Toast.LENGTH_LONG).show();
      });
    });
    // ...其他初始化代码
  }
}

4. 额外优化建议

  • 日志分级处理:开发环境直接打印控制台,生产环境将错误日志写入本地文件,待App下次启动时批量上报到服务器
  • 区分错误优先级:致命错误(导致App崩溃)优先上报,非致命错误可延迟上报
  • 容错上报逻辑:错误上报代码本身要做容错,比如网络请求失败时不要抛出新错误,避免恶性循环
  • 监控工具辅助:可以集成成熟的错误监控工具,这类工具能自动收集用户设备、App版本、错误上下文等多维度信息,降低排查成本

内容的提问来源于stack exchange,提问作者Tavojavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:55:23