使用异步等待和Redux处理错误

时间:2018-10-08 15:00:52

标签: javascript redux async-await

我想创建一个单独的类来处理我的redux动作的所有api请求,帖子等,有时这样,这样我的redux动作代码将变得更简单,工作量也更少。但是,当发生错误时,我需要确保我的操作能够捕获这些错误并将它们正确地分发给适当的reducer。我的困惑是我的api函数本身也正在捕获错误,并且我想知道如果首先发生错误,它将首先在我的api函数中被捕获,因此我不会在我的动作函数中捕获该错误,因此永远不会调度说错误?如何避免这个问题?我能不能在api函数中捕获错误,而只是以某种方式将其转移到我的操作中吗?还是我需要将requestDataFailure调度到我的api函数?谢谢。

操作:

export const fetchData = () => async (dispatch) => {
  dispatch(requestData());
  try {
    const json = await ApiClass.getData();
    dispatch(receiveData(json.data));
  } catch (error) {
    dispatch(requestDataFailure(error));
  }
};

Api类:

import HttpService from './httpServce';

export default class ApiClass {
  static async getData() {
    try {
      const response = await HttpService.get('api/get-data');
      return response.json;
    } catch (error) {
      throw Error(error.message);
    }
  }
}

1 个答案:

答案 0 :(得分:1)

(最终)它们将全部冒泡,直至达到您的主要方法。

在您的ApiClass中,您实际上是在抛出任何错误,因此该错误将冒泡到您的fetchData函数中,并被该块捕获。

您有几种方法可以做到这一点:

  • 将您的try / catch保留在ApiClass中,并将其用于更“友好的”错误消息。从HttpService.get中获取错误,并可能从服务器读取json的输出(如果不是500错误),然后根据结果抛出不同的错误。例如:
class ProductNotFound extends ApiError {
  constructor(name) {
    super(`This product: '${name}' was not found.`);
  }
}

export default class ApiClass {
  static async getProducts() {
    try {
      const response = await HttpService.get('api/get-products');
      return response.json;
    } catch (error) {
      if (error.code === 404) {
        throw new ProductNotFound();
      }
      // Check if error.response contains valid json, and if so, output a server side message?

      // Unknown error, just throw
      throw ApiUnknownError(error.message);
    }
  }
}

现在,您只需使用requestDataFailure并将error.message传递给最终用户即可。

  • 或者,您也可以只return response.json;而不包装在try / catch块中。当HttpService.get拒绝时,它将引发错误,您可以简单地使用error.message从中获取原始的HttpService.get错误消息。以此为基础执行所有还原操作。