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

Redux-Saga无法捕获React-Native-Firestore调用错误的问题咨询

问题解答

问题1:Redux-Saga中用call/fork让外层try/catch捕获错误是否可行?

这得分两种情况具体分析:

针对call

是完全可行的,但需要满足两个前提:

  • 你的createItem函数必须返回Promise(Firestore的add方法本身就返回Promise,所以要把它的执行结果return出去)
  • call是阻塞式调用,它会等待Promise完成或失败,因此Promise抛出的错误会被外层的try/catch正常捕获。

针对fork

不可行。因为fork是非阻塞的,它会启动一个独立的子任务,这个子任务的错误不会冒泡到父saga的try/catch中。如果要处理fork任务的错误,你需要:

  • 在子任务内部自行添加try/catch逻辑
  • 或者通过fork返回的task对象,监听它的失败事件,示例代码如下:
    const task = yield fork(createItem, item);
    const taskResult = yield take([task.DONE, task.FAILED]);
    if (taskResult.error) {
      // 在这里处理子任务的错误
      console.log('子任务执行失败:', taskResult.error);
    }
    

问题2:为什么Firestore权限错误没被捕获,出现未处理Promise拒绝?

你的代码存在两个核心问题:

  1. createItem函数未返回Promise
    初始代码里的createItem仅调用了Firestore的add方法,但没有return它的执行结果:

    function createItem(item) { 
      firebase.firestore().collection('todos').add(item); // 缺少return!
    }
    

    这导致不管用call还是fork,都无法追踪到这个Promise的状态,自然没法捕获它的错误。修改方式很简单:

    function createItem(item) { 
      return firebase.firestore().collection('todos').add(item);
    }
    
  2. fork的错误无法被外层try/catch捕获
    正如问题1中提到的,fork启动的子任务错误不会传递到父saga的try/catch块。如果你希望错误被外层捕获,应该用call代替fork——call会阻塞并等待Promise完成,错误会正常传递到catch块中。

修正后的完整示例代码

function createItem(item) { 
  return firebase.firestore().collection('todos').add(item);
}

export function* createItemSaga() { 
  while (true) { 
    const action = yield take(ActionTypes.AddListItem_UIRequest); 
    console.log('createItemSaga: received AddListItem_UIRequest'); 
    const { item } = action; 
    yield put({ type: ActionTypes.AddListItemRequested }); 
    try { 
      console.log('createItemSaga: createItem Start'); 
      yield call(createItem, item); // 改用阻塞式的call
      console.log('createItemSaga: createItem Ended'); 
    } catch (e) { 
      console.log('createItemSaga: error caught. Error=', e); 
      yield put({ type: ActionTypes.AddListItemRejected }); 
    } 
  } 
}

这样修改后,Firestore的权限错误就会被try/catch正常捕获,不会再出现未处理Promise拒绝的提示了。另外你提到将createItem改为生成器函数也没解决问题,大概率是因为生成器内部没有正确处理Promise的状态流转,只要确保函数返回可被saga识别的Promise(或迭代器),配合call就能正常捕获错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:27:47