如何创建用于传奇错误处理的通用包装函数?

时间:2019-02-08 15:03:11

标签: reactjs redux redux-saga

我想创建一个包装程序,该包装程序可以处理我的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);
}

2 个答案:

答案 0 :(得分:1)

为什么需要包装纸?只需将其放在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

答案 1 :(得分:1)

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

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