下面的代码是否是使用 call 或 fork 在 redux-saga 中“捕获”错误的正确方法?那就是当我有“createItem”函数时,这里不捕获任何错误是正确的,并假设这会将任何异常传递回生成器函数“createItemSaga”以捕获?
这里的第二个问题是我注意到我收到了一个 Firestore 错误传回(我正在使用 react-native-firebase)但是我没有用这段代码来捕捉它。请参阅下面的控制台输出。我创建了一个安全规则来拒绝在 Firestore 后端创建项目的尝试以对此进行测试。
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 });
}
}
}
控制台输出为:
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)
注意:这里是否提出了潜在问题是与此库有关的情况:https ://github.com/invertase/react-native-firebase/issues/727
补充说明:
- 如果我在“yield fork(createItem, item);”行中使用“call”而不是“fork”,我会得到相同的结果
- 如果我将更新尝试合并到生成中,我也会得到相同的结果,如下所示:
代码:
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 });
}
}
}
附加说明 2:
- 当我将“createItem”函数变成生成器时,得到相同的结果:
代码:
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 });
}
}
}
安慰:
createItemSaga: createItem Start
createItem: Start
createItem: End
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)