0
votes

I have a saga:

function* mySaga() {
  try {
    yield put({type: 'ACTION_TYPE'})
  } catch (e) {
    handleError(e)
  }
}

If the reducer that handles ACTION_TYPE throws an error, the catch block won't run. At least not within my tests.

I have set up a Redux middleware to catch all errors and then dispatch an action that can update the store accordingly.

const errorHandlerMiddleware = store => next => action => {
  try {
    return next(action)
  } catch (err) {
    return next({
      type: 'START_ERROR_STATE',
      err: err
    })
  }  
}

But if I have another saga that puts two sequential actions:

function* anotherSaga() {
  try {
    yield put({type: 'ACTION_TYPE'})
    yield put({type: 'ANOTHER_ACTION_TYPE'})
  } catch (e) {
    handleError(e)
  }
}

Even if the reducer that handles the action of type ACTION_TYPE throws an error, anotherSaga will still dispatch ANOTHER_ACTION_TYPE. I don't want this to happen.

I have implemented a race:

function* raceSaga() {
  const { error} = yield race({
    main: call(anotherSaga),
    error: take('START_ERROR_STATE')
  })

  if (main) {
     yield put({type: 'SUCCESS_ACTION'})
  } else if (error) {
     yield put({type: 'ERROR_ACTION'})
  }
}

I'm not sure if it's the best approach.

1

1 Answers

0
votes

There is something wrong with your redux setup. Citing redux documentation:

The reducer is a pure function that takes the previous state and an action, and returns the next state

Which means that you can't throw errors inside reducers. It should take state, action object and return you next state. I suggest that you revisit redux documantation or some tutorial.