I'm using createAsyncThunk to handle all my api resquests. However, when I'm doing the error handling in the rejected action, I can't seem to access the original body returned from the response.
export const addContact = createAsyncThunk('contacts/addContactStatus', async (obj) => {
const { data } = await api.post('/contact/', obj);
return data;
});
const contactsSlice = createSlice({
name: 'contacts',
initialState,
reducers,
extraReducers: {
[addContact.pending]: (state) => {
state.loading = true;
},
[addContact.rejected]: (state, action) => {
state.loading = false;
// I want to use error.response.data.message, which is how I normally
// handle errors when using Axios directly,
// But I can't seem to access it
message.error(action.error.message);
},
[addContact.fulfilled]: (state, action) => {
message.success('Contato criado com sucesso');
state.loading = false;
state.entities.push(action.payload);
state.selected.push(action.payload);
},
}
I really don't want to do the usual try/catch, since it kinda defeats the purpose of having the status action creators, which I think are great for making my code cleaner. I've looked through the past issues, but maybe I'm missing something. It would be great if someone could help me.
Thanks in advance!
Hey @will-amaral , your error will be serialized via miniSerializeError unless you specifically catch and return it with rejectWithValue as shown here. There was a good amount of discussion about this behavior and why it was decided to use rejectWithValue that you can skim through here: https://github.com/reduxjs/redux-toolkit/issues/390
In your example, you'd need to do this:
export const addContact = createAsyncThunk('contacts/addContactStatus', async (obj, { rejectWithValue }) => {
try {
const { data } = await api.post('/contact/', obj);
return data;
} catch (err) {
return rejectWithValue(err.response.data); // or whatever path you normally reference
});
Yep. createAsyncThunk defaults to the simplest approach, which is the entire successful return value becomes payload, and the entire thrown error gets serialized and included. If you need more specific details, it's up to you to parse and include them in the rejection yourself.
Thanks guys!
Most helpful comment
Hey @will-amaral , your error will be serialized via
miniSerializeErrorunless you specifically catch and return it withrejectWithValueas shown here. There was a good amount of discussion about this behavior and why it was decided to userejectWithValuethat you can skim through here: https://github.com/reduxjs/redux-toolkit/issues/390In your example, you'd need to do this: