React Native 0.74.x及以上版本全局错误处理器实现方案咨询
React Native 0.74.x 全局错误处理方案(TypeScript环境)
问题背景
我正尝试在TypeScript环境下,为React Native插件或应用层面创建全局错误处理器,以捕获所有未处理异常并记录日志。当前使用React Native 0.74.x版本:
- 找到
react-native-exception-handler包,但该包已3年未更新,不再维护。 - 尝试了Error Boundaries方案,但无法满足需求:
- 测试代码中,按钮点击事件内的
JSON.parse('Invalid JSON String')异常未被捕获 - Error Boundary本身无法捕获以下场景的错误:
- 事件处理程序
- 异步代码(如
setTimeout或requestAnimationFrame回调) - 服务器端渲染
- 错误边界自身抛出的错误(而非其子组件)
- 测试代码中,按钮点击事件内的
适配RN 0.74.x的全局错误处理方案
1. JS层全局异常监听
通过React Native提供的全局钩子,捕获JS层面的未处理异常:
未处理Promise拒绝监听
在应用入口文件(如App.tsx)中添加:
Promise.onUnhandledRejection = (error: Error) => { console.error('未处理的Promise拒绝:', error); // 此处添加日志上报或自定义处理逻辑 };
全局同步错误监听
同样在入口文件中注册:
global.ErrorUtils.setGlobalHandler((error: Error, isFatal: boolean) => { console.error(`${isFatal ? '致命' : '非致命'}JS错误:`, error); // 致命错误场景下,应用可能即将崩溃,优先完成日志上报 });
2. 原生层异常捕获(iOS + Android)
要覆盖原生代码导致的崩溃,需分别在iOS和Android项目中添加捕获逻辑:
iOS端
在AppDelegate.mm中修改didFinishLaunchingWithOptions方法:
#import <Foundation/Foundation.h> void uncaughtExceptionHandler(NSException *exception) { NSLog(@"原生iOS未捕获异常: %@\n调用栈: %@", exception, exception.callStackSymbols); // 可将异常信息写入本地文件或上报至日志服务 } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); // ...原有代码 return YES; }
Android端
在MainApplication.java的onCreate方法中添加:
import android.util.Log; import java.lang.Thread.UncaughtExceptionHandler; @Override public void onCreate() { super.onCreate(); Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable throwable) { Log.e("NativeAndroidError", "未捕获原生异常", throwable); // 执行日志上报或崩溃前的收尾逻辑 } }); // ...原有代码 }
3. Error Boundary补充UI渲染错误
虽然Error Boundary无法覆盖所有场景,但仍可用于捕获组件渲染阶段的错误。针对事件处理中的错误,可封装高阶组件自动捕获:
事件处理错误捕获高阶组件
import React from 'react'; // 封装支持onPress事件的错误捕获高阶组件,可按需扩展其他事件 const withEventErrorHandling = <P extends { onPress?: () => void }>( Component: React.ComponentType<P> ) => { return (props: P) => { const wrappedOnPress = props.onPress ? () => { try { props.onPress!(); } catch (error) { console.error('事件处理错误:', error); // 日志上报逻辑 } } : undefined; return <Component {...props} onPress={wrappedOnPress} />; }; }; // 使用示例: // const SafeCustomButton = withEventErrorHandling(CustomButton);
4. 维护中的第三方包替代
若不想手动实现全量逻辑,可选择以下适配RN 0.74+的维护中包:
react-native-error-reporter:支持JS和原生层错误捕获,内置日志管理能力sentry-react-native:成熟的错误追踪方案,覆盖JS/原生错误,支持性能监控(需接入Sentry服务)
关键注意事项
- 全局错误处理器需在应用启动时尽早注册,避免遗漏初始化阶段的错误
- 致命错误场景下,JS层只能完成崩溃前的最后一次日志上报,无法阻止崩溃,需依赖原生层处理
- 异步代码(如
setTimeout、fetch回调)中的同步错误,需手动添加try/catch,或用async/await结合捕获逻辑
内容的提问来源于stack exchange,提问作者Šemsudin Tafilović
相关产品推荐
相关产品推荐

