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… :/
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.