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

React Native中react-native-exception-handler无法捕获Promise内错误

React Native中react-native-exception-handler无法捕获Promise内部错误的解决方法

问题说明

在运行于Android虚拟设备(API 23)的React Native项目中,使用react-native-exception-handler实现全局错误统一处理时,普通同步JS错误可被正常捕获并弹出自定义错误弹窗,但Promise内部抛出的错误仅会在日志中输出警告,无法触发自定义错误处理逻辑。

环境配置

  • Android Gradle Plugin版本:7.2.0
  • Gradle版本:7.4.2
  • 项目build.gradle核心配置:
buildscript {
    ext {
        buildToolsVersion = "31.0.0"
        minSdkVersion = 21
        compileSdkVersion = 31
        targetSdkVersion = 31
        // 其他配置...
    }
}

现有代码示例

App.js代码

import React, { Component } from 'react';
import {
  StyleSheet,
  Button,
  View,
  Alert,
} from 'react-native';
import { setJSExceptionHandler } from 'react-native-exception-handler';

const errorHandler = (e, isFatal) => {
    if (isFatal) {
      Alert.alert(
          'Unexpected error occurred',
          `
          Error: ${(isFatal) ? 'Fatal:' : ''} ${e.name} ${e.message}
  
          We have reported this to our team ! Please close the app and start again!
          `,
        [{
          text: 'Close'
        }]
      );
    } else {
      console.log(e); 
    }
};
  
setJSExceptionHandler(errorHandler, true);

export default class App extends Component {
    constructor() {
        super();
    }

    causeJSError () {
        throw new Error('THIS IS A CUSTOM UNHANDLED JS ERROR');
    }

    causeJSPromiseError () {
        new Promise((resolve, reject) => {
            throw new Error("Whoops!"); 
        }).catch(error => {
            throw error;
        });
    }

  render() {
    return (
    <View style={styles.container}>
        <Button onPress={this.causeJSError.bind(this)} title="CAUSE JS ERROR" color="#841584" style={{flex:1}}/>     
        <Button onPress={this.causeJSPromiseError.bind(this)} title="CAUSE JS PROMISE ERROR" color="#841584" style={{flex:1}}/>     
    </View>
    );
 }
};

const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
      backgroundColor: '#F5FCFF',
    },
});

测试现象

  • 点击「CAUSE JS ERROR」按钮:全局异常处理器正常触发,弹出自定义错误弹窗。
  • 点击「CAUSE JS PROMISE ERROR」按钮:无自定义错误弹窗,仅日志输出警告:
LOG  Running "handlertest" with {"rootTag":21}
WARN  Possible Unhandled Promise Rejection (id: 0):
Error: Whoops!
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.handlertest&modulesOnly=false&runModule=true:112203:26
// 其余调用栈日志...

解决方案

react-native-exception-handler的setJSExceptionHandler仅处理同步JS错误,Promise未处理的拒绝属于异步错误场景,需要使用专门的setUnhandledRejectionHandler方法来捕获。

修改App.js代码,添加Promise未处理拒绝的处理器:

import React, { Component } from 'react';
import {
  StyleSheet,
  Button,
  View,
  Alert,
} from 'react-native';
import { setJSExceptionHandler, setUnhandledRejectionHandler } from 'react-native-exception-handler';

const errorHandler = (e, isFatal) => {
    if (isFatal) {
      Alert.alert(
          'Unexpected error occurred',
          `
          Error: ${(isFatal) ? 'Fatal:' : ''} ${e.name} ${e.message}
  
          We have reported this to our team ! Please close the app and start again!
          `,
        [{
          text: 'Close'
        }]
      );
    } else {
      console.log(e); 
    }
};
  
setJSExceptionHandler(errorHandler, true);
// 添加Promise未处理拒绝处理器
setUnhandledRejectionHandler((reason) => {
    // 将Promise拒绝视为非致命错误,复用现有错误处理逻辑
    errorHandler(reason, false);
    // 如果需要视为致命错误,可传true:errorHandler(reason, true);
});

export default class App extends Component {
    // 其余代码保持不变...
}

原理说明

Promise的未处理拒绝不会触发同步的throw错误流,而是属于单独的异步错误事件。react-native-exception-handler提供了setUnhandledRejectionHandler方法专门监听这类错误,通过注册该处理器,就能将Promise内部抛出的错误纳入全局错误处理体系中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 07:36:18