从thunk捕获错误到功能组件的反应

发布于 2025-02-09 05:47:47 字数 2525 浏览 1 评论 0原文

如何从thunk中的异步方法中捕获错误? 例如,我有以下thunk:

export const updateCostCenter = (data: Record<string, unknown>) => async (dispatch: Dispatch<IWorkforceState>) => {
  dispatch(requestUpdateCostCenter());

  return api('put', `${costCenterUrl}/${data.rowId}`, data)
    .then(response => {
      return dispatch(receiveUpdateCostCenter(response.data));
    })
    .catch(err => {
      return dispatch(errorUpdateCostCenter(err.response?.data?.description));
    });
};

在功能组件中,以下调用thunk的异步方法:

 props.updateCostCenter(valueToSubmit).then(
        () => {
          props.showToastNotification('success', 'Successful', props.translate('cost_center_successfully_updated'));
          AmplitudeService.logEvent(props.translate('edit_cost_center'));
          props.hideDialog();
          resetForm();
          setSubmitting(false);
          if (props.loadData) {
            props.loadData();
          }
          return
        }
      ).catch(() => {
        props.showToastNotification('error', 'Error', props.translate('cost_center_update_error'))
      });

不幸的是,我不知道为什么在错误的情况下它不会从功能组件中输入捕获量。我尝试添加投掷typeerror()在派遣错误操作后,它有效,但是Thunk单元测试在管道上失败。

这是测试:

 it('update cost center success', function() {
    mockAdd.mockImplementation(
      () =>
        Promise.resolve({
            data: costCenter,
          } as any)
    );

    const expectedActions = [
      { type: WorkforceActions.REQUEST_UPDATE_COST_CENTER },
      { type: WorkforceActions.RECEIVE_UPDATE_COST_CENTER, costCenter },
    ];

    store.dispatch(updateCostCenter({ data: costCenter }) as any).then(() => {
      expect(store.getActions()).toEqual(expectedActions);
      expect(api).toHaveBeenCalled();
      return
    }).catch((unexpectedErr: any) => console.log(`Unexpectedly rejected promise ${unexpectedErr}`));
  });

  it('update cost center error', function() {
    mockAdd.mockImplementation(
      () =>
        Promise.reject({
            response: { data: { description: 'dummy-message' } },
          } as any)
    );

    const expectedActions = [
      { type: WorkforceActions.REQUEST_UPDATE_COST_CENTER },
      { type: WorkforceActions.ERROR_UPDATE_COST_CENTER, message: 'dummy-message' },
    ];

    store.dispatch(updateCostCenter({ data: costCenter }) as any).catch(() => {
      expect(store.getActions()).toEqual(expectedActions);
      expect(api).toHaveBeenCalled();
    });
  });

How can I catch the errors from async method in the thunk into the Functional Components?
For example I have the following thunk:

export const updateCostCenter = (data: Record<string, unknown>) => async (dispatch: Dispatch<IWorkforceState>) => {
  dispatch(requestUpdateCostCenter());

  return api('put', `${costCenterUrl}/${data.rowId}`, data)
    .then(response => {
      return dispatch(receiveUpdateCostCenter(response.data));
    })
    .catch(err => {
      return dispatch(errorUpdateCostCenter(err.response?.data?.description));
    });
};

and in the functional component the following asynchronous method that calls the thunk:

 props.updateCostCenter(valueToSubmit).then(
        () => {
          props.showToastNotification('success', 'Successful', props.translate('cost_center_successfully_updated'));
          AmplitudeService.logEvent(props.translate('edit_cost_center'));
          props.hideDialog();
          resetForm();
          setSubmitting(false);
          if (props.loadData) {
            props.loadData();
          }
          return
        }
      ).catch(() => {
        props.showToastNotification('error', 'Error', props.translate('cost_center_update_error'))
      });

Unfortunately, I don't know why in case of error it doesn't enter into the catch from the functional component. I tried to add throw TypeError() after the dispatch of the error action, it works, but the thunk unit test fails on the pipeline.

This are the tests:

 it('update cost center success', function() {
    mockAdd.mockImplementation(
      () =>
        Promise.resolve({
            data: costCenter,
          } as any)
    );

    const expectedActions = [
      { type: WorkforceActions.REQUEST_UPDATE_COST_CENTER },
      { type: WorkforceActions.RECEIVE_UPDATE_COST_CENTER, costCenter },
    ];

    store.dispatch(updateCostCenter({ data: costCenter }) as any).then(() => {
      expect(store.getActions()).toEqual(expectedActions);
      expect(api).toHaveBeenCalled();
      return
    }).catch((unexpectedErr: any) => console.log(`Unexpectedly rejected promise ${unexpectedErr}`));
  });

  it('update cost center error', function() {
    mockAdd.mockImplementation(
      () =>
        Promise.reject({
            response: { data: { description: 'dummy-message' } },
          } as any)
    );

    const expectedActions = [
      { type: WorkforceActions.REQUEST_UPDATE_COST_CENTER },
      { type: WorkforceActions.ERROR_UPDATE_COST_CENTER, message: 'dummy-message' },
    ];

    store.dispatch(updateCostCenter({ data: costCenter }) as any).catch(() => {
      expect(store.getActions()).toEqual(expectedActions);
      expect(api).toHaveBeenCalled();
    });
  });

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

亣腦蒛氧 2025-02-16 05:47:47

因为您没有返回错误。

export const updateCostCenter = (data: Record<string, unknown>) => async (dispatch: Dispatch<IWorkforceState>) => {
  dispatch(requestUpdateCostCenter());

  return api('put', `${costCenterUrl}/${data.rowId}`, data)
    .then(response => {
      dispatch(receiveUpdateCostCenter(response.data));
      return response;
    })
    .catch(err => {
      dispatch(errorUpdateCostCenter(err.response?.data?.description));
      throw err; // or throw new Error();
    });
};

Because you don't return an error.

export const updateCostCenter = (data: Record<string, unknown>) => async (dispatch: Dispatch<IWorkforceState>) => {
  dispatch(requestUpdateCostCenter());

  return api('put', `${costCenterUrl}/${data.rowId}`, data)
    .then(response => {
      dispatch(receiveUpdateCostCenter(response.data));
      return response;
    })
    .catch(err => {
      dispatch(errorUpdateCostCenter(err.response?.data?.description));
      throw err; // or throw new Error();
    });
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文