如何为 saga 错误处理创建通用包装函数?

How to create a generic wrapper function for saga error handling?

我想创建一个包装器来处理我的 sagas 中的 try-catch 子句,使它们更简洁一些。到目前为止,我有下面的代码,但它不起作用。

export function* withErrorHandler(fn, errorFn) {
  try {
    fn();
  } catch (e) {
    yield put(errorFn(parseError(e)));
  }
}

export function* logoutSaga() {
  yield withErrorHandler(function*() {
    yield put(logoutRequest());
    yield call(api.logout);
    yield localStorage.clear();
    yield put(logoutSuccess());
  }, logoutFailure);
}

为什么需要包装器?只需将其放在 try/catch 块中即可:

export function* logoutSaga() {
  try {
    yield put(logoutRequest());
    yield call(api.logout);
    yield localStorage.clear();
    yield put(logoutSuccess());
  } catch(e) {
    yield put(logoutFailure(parseError(e)));
  }
}

此外,通过将 API 函数包装在包装器中,您可以完全消除解析错误的需要。例如:

class ApiError {
    constructor(err, helpful) {
        this.original = err;
        this.helpful = helpful;
    }
}

const logout = () => { 
    try {
        return axios.post("accounts/logout/");
    } catch (err) {
        throw new ApiError(err, 'There was a problem logging out.');
    }
}

然后在您的错误处理函数中,您可以检查抛出的错误是否为“instanceof ApiError”,并向最终用户显示err.helpful。还可以把ApiError的构造函数更进一步,解析原来的错误,根据返回的结果再修改this.helpful

您传递的是生成器,而不是函数,因此您需要正确调用它。你应该像这样改变你的包装器

export function* withErrorHandler(fn, errorFn) {
 try {
  yield fn();
 } catch (e) {
...