简体   繁体   中英

Redux Saga does not work after any error. It totally stops working and need to refresh the page

Redux Saga does not work after any error. It totally stops working and need to refresh the page. Working well when does not generate any error.

I want whether any error occurred the page should running if click the process again and fetch data from API.

If anyone gives any suggestion/solution, please.

My axios call as like below,

export async function getWithPagination(pageNumber, pageSize, searchObject) {
  try {
    const response = await axios.get(
      uri.ApiBaseUrl + "Voucher/GetWithPagination",
      {
        params: {
          ...searchObject,
          pageNumber,
          pageSize,
        },
      }
    );
    return { response };
  } catch (error) {
    return { error };
  }
}

export async function createVoucher(voucher) {
  console.log("createVoucher service=> ", voucher);
  try {
    const response = await axios.post(uri.ApiBaseUrl + "Voucher", voucher, {});
    return { response };
  } catch (error) {
    return { error };
  }
}

The reducer, action, saga like below

import { put, takeLatest, call } from "redux-saga/effects";
import {
  getWithPagination,  
  createVoucher  
} from "../../services-crud/accounting/vouchersCrud";

export const reducer = (state = voucherState, action) => {
    case actionTypes.VoucherGetRequested: {
      return {
        ...state,
        voucherGridObj: {
          paging: {},
          links: {},
          lists: [],
        },
        isGridLoading: true,
      };
    }
    case actionTypes.VoucherGetSucceed: {
      return { ...state, voucherGridObj: action.data, isGridLoading: false };
    }
    case actionTypes.VoucherGetFailed: {
      return { ...state, isGridLoading: false };
    }
    case actionTypes.VoucherCreateRequested: {
      return { ...state };
    }
    case actionTypes.VoucherCreateSucceed: {
      return {
        ...state,
        voucherObj: { ...voucherInit },
        voucherDetailsList: [],
        voucherGridObj: {
          ...state.voucherGridObj,
          lists: [{ ...action.data.voucher }, ...state.voucherGridObj.lists],
        },
        isSuccess: false,
        isDataSyncNeeded: true,
      };
    }
    case actionTypes.VoucherCreateFailed: {
      return { ...state, isSuccess: false, isDataSyncNeeded: false };
    }
}

export const actions = {
     voucherGetRequested: (pageNumber, pageSize, searchObject) => ({
    type: actionTypes.VoucherGetRequested,
    pageNumber: pageNumber,
    pageSize: pageSize,
    searchObject: searchObject,
  }),
  voucherGetSucceed: (data) => ({
    type: actionTypes.VoucherGetSucceed,
    data: data,
  }),
  voucherGetFailed: () => ({ type: actionTypes.VoucherGetFailed }),

  voucherCreate: (voucherObj, voucherImage, gurdianImage) => ({
    type: actionTypes.VoucherCreate,
    voucherObj: voucherObj,
    voucherImage: voucherImage,
    gurdianImage: gurdianImage,
  }),
  voucherCreateRequested: () => ({
    type: actionTypes.VoucherCreateRequested,
  }),
  voucherCreateSucceed: (data) => ({
    type: actionTypes.VoucherCreateSucceed,
    data: data,
  }),
  voucherCreateFailed: () => ({
    type: actionTypes.VoucherCreateFailed,
  }),
};

export function* saga() {

    try {
    yield takeLatest(
      actionTypes.VoucherGetRequested,
      function* voucherRequested(action) {
        const { response, error } = yield call(() =>
          getWithPagination(
            action.pageNumber,
            action.pageSize,
            action.searchObject
          )
        );

        if (response) {
          yield put(actions.voucherGetSucceed(response.data));
        } else {
          NotificationMessage(errorResponseProcess(error.response));
          yield put(actions.voucherGetFailed(error));
        }
      }
    );
  } catch (error) {
    NotificationMessage(errorResponseProcess(error.response));
    yield put(actions.voucherGetFailed(error));
  }

   try {
    yield takeLatest(
      actionTypes.VoucherCreate,
      function* createsvoucher(action) {
        yield put(actions.voucherCreateRequested());
        const { response, error } = yield call(() =>
          createVoucher(
            action.voucherObj,
            action.voucherImage,
            action.gurdianImage
          )
        );
        if (response) {
          NotificationMessage(response.data.notification);

          yield put(actions.voucherCreateSucceed(response.data.data));
          yield put(actions.voucherResetFlag());
        } else {
          NotificationMessage(errorResponseProcess(error.response));
          yield put(actions.voucherCreateFailed(error));
        }
      }
    );
  } catch (error) {
    NotificationMessage(errorResponseProcess(error.response));
    yield put(actions.voucherCreateFailed(error));
  }

}

The root reducer & store is below

import { all } from "redux-saga/effects";
import createSagaMiddleware from "redux-saga";
import { combineReducers, applyMiddleware, createStore } from "redux";

import * as accountsReportCrud from "./accounts-chart-duck/accountsReportCrudDuck";
import * as vouchersCrud from "./voucher-duck/voucherCrudDuck";

export const rootReducer = combineReducers({

  accountsCrud: accountsCrud.reducer,
  accountsReportCrud: accountsReportCrud.reducer,

});

export function* rootSaga() {
  yield all([

  accountsCrud.saga(),
  accountsReportCrud.saga(),
   ...
  
  ]);
}

const sagaMiddleware = createSagaMiddleware();
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));

sagaMiddleware.run(rootSaga);

export default store;

In your root saga, you can spawn the tasks instead of all / fork so that one saga's error doesn't crash all the sagas.

Redux-saga docs on detached fork (spawn) :

Uncaught errors from spawned tasks are not bubbled up to the parent.

I think this formation of sagas will does the trick

function* function_name({ payload }){
  //code here
}

export function* function_name_sagas() {
    yield takeEvery(action_type, function_name);
}

export default function* rootSaga() {
    yield all([
        fork(function_name_sagas),
    ]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM