使用redux-saga无法捕获错误? (通过react-native-firestore进行firestore调用时)

时间:2018-01-06 02:37:45

标签: redux-saga react-native-firebase

以下代码是否正确的方式来捕捉"使用call或fork在redux-saga中出错?那是我有" createItem"函数是正确的,不捕获任何错误,并假设这将传回生成器函数的任何异常" createItemSaga"去抓?

这里的第二个问题是我注意到我传回了一个firestore错误(我使用的是react-native-firebase)但是我没有用这个代码来捕获它。请参阅下面的控制台输出。我创建了一个安全规则来拒绝在firestore后端创建项目的尝试来测试它。

$bios[$arr3] = "    Available"
$bios[$arr2] = "    *Hidden"

控制台输出是:

function createItem(item) {
  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 fork(createItem, item);
      console.log('createItemSaga: createItem Ended');  // <-- This is reached! But why.
    } catch (e) {
      console.log('createItemSaga: error caught. Error=');  <-- Why isn't this point reached
      console.log(pf(e));
      yield put({ type: ActionTypes.AddListItemRejected });
    }
  }
}

注意:此处引发潜在问题的情况与此库有关:https://github.com/invertase/react-native-firebase/issues/727

附加说明:

  • 如果我使用&#34; call&#34;我会得到相同的结果而不是&#34; fork&#34;在行&#34; yield fork(createItem,item);&#34;
  • 如果我在生成中包含更新尝试,我也会得到相同的结果:

代码:

createItemSaga: recived AddListItem_UIRequest
createItemSaga: createItem Start
createItemSaga: createItem Ended

Possible Unhandled Promise Rejection (id: 0):
Error: Firestore: The caller does not have permission to execute the specified operation. (firestore/permission-denied).
Error: Firestore: The caller does not have permission to execute the specified operation. (firestore/permission-denied).
    at createErrorFromErrorData (/Users/Greg/Dropbox/source_reactnative/gcTodo/.vscode/.react/index.bundle:1822:15)
    at /Users/Greg/Dropbox/source_reactnative/gcTodo/.vscode/.react/index.bundle:1775:25
    at MessageQueue.__invokeCallback (/Users/Greg/Dropbox/source_reactnative/gcTodo/.vscode/.react/index.bundle:2133:16)
    at /Users/Greg/Dropbox/source_reactnative/gcTodo/.vscode/.react/index.bundle:1950:16
    at MessageQueue.__guard (/Users/Greg/Dropbox/source_reactnative/gcTodo/.vscode/.react/index.bundle:2068:9)
    at MessageQueue.invokeCallbackAndReturnFlushedQueue (/Users/Greg/Dropbox/source_reactnative/gcTodo/.vscode/.react/index.bundle:1949:12)
    at /Users/Greg/Dropbox/source_reactnative/gcTodo/.vscode/.react/debuggerWorker.js:126:58
    at process.<anonymous> (/Users/Greg/Dropbox/source_reactnative/gcTodo/.vscode/.react/debuggerWorker.js:35:9)
    at emitTwo (events.js:125:13)
    at process.emit (events.js:213:7)

附加说明2:

  • 当我转动&#34; createItem&#34;时获得相同的结果功能到发电机:

代码:

export function* createItemSaga() {
  while (true) {
    const action = yield take(ActionTypes.AddListItem_UIRequest);
    const { item } = action;
    yield put({ type: ActionTypes.AddListItemRequested });
    try {
      console.log('createItemSaga: createItem Start');
      firebase.firestore().collection('todos').add(item);
      console.log('createItemSaga: createItem Ended');
    } catch (e) {
      console.log('createItemSaga: error caught. Error='); 
      console.log(pf(e));
      yield put({ type: ActionTypes.AddListItemRejected });
    }
  }
}

控制台:

export function* createItem(item) {
  try {
    console.log('createItem: Start');
    firebase.firestore().collection('todos').add(item);
    console.log('createItem: End');
  } catch (e) {
    console.log('createItem: error');
    console.log(pf(e));
  }
}

    export function* createItemSaga() {
      while (true) {
        const action = yield take(ActionTypes.AddListItem_UIRequest);
        const { item } = action;
        yield put({ type: ActionTypes.AddListItemRequested });

        try {
          console.log('createItemSaga: createItem Start');
          yield call(createItem, item);
          console.log('createItemSaga: createItem Ended');
        } catch (e) {
          console.log('createItemSaga: error caught. Error='); 
          console.log(pf(e));
          yield put({ type: ActionTypes.AddListItemRejected });
        }
      }
    }

2 个答案:

答案 0 :(得分:0)

首先,我认为createItem应该是一个生成器(或者换句话说是一个传奇)。然后你不需要forkcall。这是因为forkcall时没有阻止。这就是你获得控制台日志的原因。我想如果createItem是一个生成器,那么try-catch块就会起作用。

答案 1 :(得分:0)

没有让它使用createItem作为一个单独的函数,但是现在通过将所有内容收缩到一个生成器来捕获错误:

export function* createItemSaga() {
  while (true) {
    const action = yield take(ActionTypes.AddListItem_UIRequest);
    const { item } = action;
    yield put({ type: ActionTypes.AddListItemRequested });
    try {
      const ref = firebase.firestore().collection('todos');
      yield call([ref, ref.add], item);
      yield put({ type: ActionTypes.AddListItemFulfilled });
    } catch (e) {
      console.log('createItemSaga: error caught. Error='); 
      console.log(pf(e));
      yield put({ type: ActionTypes.AddListItemRejected });
    }
  }
}