Search code examples
javascriptreactjsreduxreact-reduxredux-saga

How can i stop redux action? when i get error


If an error occurs in the yield call(refresh) of the getPost function, the GETPOST_REQUEST action continues regardless of whether an error has occurred.

However, if an error occurs in the getPost function I don’t want the action to run anymore and stop and end like

    yield put({
          type: REFRESH_FAILURE,
          error: err.response.data,
        });

this is my code how can i fix?

    function getPostAPI(data) {
      return axiosInstace.post("/kakao/getpost", data);
    }

    function* getPost(action) {
      try {
        const result = yield call(getPostAPI, action.data);
        yield put({
          type: GETPOST_SUCCESS,
          data: result.data,
        });
      } catch (err) {
        if (err.response.data === "jwtEx") {
          yield call(refresh);      // if this error i want to stop .

        
          yield put(action);
        } else {
          yield put({
            type: GETPOST_FAILURE,
            error: err.response.data,
          });
        }
      }
    }

    function refreshAPI() {
      // console.log('data::', data);
      return axiosInstace.post("/kakao/refresh");
    }

    function* refresh() {
      try {
        const result = yield call(refreshAPI);
        yield AsyncStorage.setItem(
          "accesstoken",
          `${result.data.accessToken}`,
          () => {
            // console.log('accesstoken 재발급 저장 완료');
            console.log("accesstoken3333333333333333333", result.data.accessToken);
          }
        );
        yield put({
          type: REFRESH_SUCCESS,
          data: result.data,
        });
      } catch (err) {
        console.log("refresh err.response.data:", err.response.data);
        yield put({
          type: REFRESH_FAILURE,
          error: err.response.data,
        });
      }
    }

Solution

  • You can make a small update to the code by doing the following:

    • return a boolean value from your refresh generator function.

      The boolean would be:

      • true if refresh was successful
      • false if refresh failed.
    • set yield call(refresh); to a const declaration to capture this returned boolean value

    • if this captured boolean value is false, exit the generator function by returning early

    Try the code below.

    function getPostAPI(data) {
      return axiosInstace.post('/kakao/getpost', data);
    }
    
    function* getPost(action) {
      try {
        const result = yield call(getPostAPI, action.data);
        yield put({
          type: GETPOST_SUCCESS,
          data: result.data,
        });
      } catch (err) {
        if (err.response.data === 'jwtEx') {
          const refreshSuccess = yield call(refresh);
          if (!refreshSuccess) {
            return;
          }
    
          yield put(action);
        } else {
          yield put({
            type: GETPOST_FAILURE,
            error: err.response.data,
          });
        }
      }
    }
    
    function refreshAPI() {
      return axiosInstace.post('/kakao/refresh');
    }
    
    /**
     * @returns {boolean} 
     * - `true` if refresh is successful
     * - `false` if refresh failed
     */
    function* refresh() {
      let refreshSuccess;
      try {
        const result = yield call(refreshAPI);
        yield AsyncStorage.setItem(
          'accesstoken',
          `${result.data.accessToken}`,
          () => {
            // console.log('accesstoken 재발급 저장 완료');
            console.log('accesstoken3333333333333333333', result.data.accessToken);
          }
        );
        yield put({
          type: REFRESH_SUCCESS,
          data: result.data,
        });
        refreshSuccess = true;
      } catch (err) {
        console.log('refresh err.response.data:', err.response.data);
        yield put({
          type: REFRESH_FAILURE,
          error: err.response.data,
        });
        refreshSuccess = false;
      } finally {
        return refreshSuccess;
      }
    }