Search code examples
reduxasync-awaittry-catchdispatch

Redux async actions: Does it make any difference to put initial dispatch into the try block?


Consider I am making a pretty generic api call using redux async action. There is an "INIT" dispatch and either "SUCCESS" or "FAILURE", regarding of the result.

Does it make any difference to put the "INIT" dispatch into the try catch block?

OPTION A (outside the try catch block):

export const doSomething = data => async dispatch => {
  dispatch(doSomethingInit()) // <-- outside try block
  try {
    let response = await client.get("/api")
    if (response) {
      dispatch(doSomethingSuccess(response.data))
    }
  } catch (error) {
    dispatch(doSomethingFailure(error))
  }
}

OPTION B (inside the try catch block):

export const doSomething = data => async dispatch => {
  try {
    dispatch(doSomethingInit()) // <-- inside the try block
    let response = await client.get("/api")
    if (response) {
      dispatch(doSomethingSuccess(response.data))
    }
  } catch (error) {
    dispatch(doSomethingFailure(error))
  }
}

I would say it is just a subtle inessential detail, however I do spend a minute thinking about it almost every time I write a new async action… :/


Solution

  • I usually avoid thinking that things will not throw.

    What if it throws? What code is going to handle it? You might have an outer try-catch block, but now something that happened during doSomething is being handled somewhere else.

    I think that since your function/thunk is "trying" to doSomething, it should be responsible for trying and catching anything that might happen during its life cycle. Even if, in theory, it wouldn't happen at that point.

    So I usually go with Option B.

    export const doSomething = data => async dispatch => {
      try {
        dispatch(doSomethingInit()) // <-- inside the try block
        let response = await client.get("/api")
        if (response) {
          dispatch(doSomethingSuccess(response.data))
        }
      } catch (error) {
        console.error(error);                   // YOU MIGHT LOG IT HERE
        dispatch(doSomethingFailure(error))
      }
    }
    

    I also think the code reads better with everything inside the try-catch block.