'Redux toolkit thunk action generic error handler
I'm enjoying redux-toolkit, but I'm wondering if there is a way to add a generic error handler for any rejected thunk? Just like the browser has the unhandledrejection event you can listen to, I'd like to report any rejected promises to my error tracker.
Solution 1:[1]
Create an error state slice hold the global error and use isRejected matching function to check whether an action is a 'rejected' action creator from the createAsyncThunk promise lifecycle.
E.g.
import { configureStore, createAsyncThunk, createSlice, isRejected, isRejectedWithValue } from '@reduxjs/toolkit';
const thunkA = createAsyncThunk('a', async (_, thunkAPI) => {
return thunkAPI.rejectWithValue('error a');
});
const thunkB = createAsyncThunk('b', async (_, thunkAPI) => {
return Promise.reject('error b');
});
const thunkC = createAsyncThunk('c', async (_, thunkAPI) => {
return { name: 'c' };
});
const thunkASlice = createSlice({
name: 'thunkA',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(thunkA.fulfilled, (state, action) => {
state.name = (action.payload as any).name;
});
},
});
const thunkBSlice = createSlice({
name: 'thunkB',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(thunkA.fulfilled, (state, action) => {
state.name = (action.payload as any).name;
});
},
});
const thunkCSlice = createSlice({
name: 'thunkC',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(thunkA.fulfilled, (state, action) => {
state.name = (action.payload as any).name;
});
},
});
const errorSlice = createSlice({
name: 'error',
initialState: {
message: '',
},
reducers: {},
extraReducers: (builder) => {
builder.addMatcher(isRejected, (state, action) => {
// global error handle reducer
state.message = 'some thunk rejected';
});
},
});
const store = configureStore({
reducer: {
error: errorSlice.reducer,
a: thunkASlice.reducer,
b: thunkBSlice.reducer,
c: thunkCSlice.reducer,
},
});
store.subscribe(() => {
console.log('state:', store.getState());
});
// store.dispatch(thunkA());
store.dispatch(thunkB());
store.dispatch(thunkC());
Final state output:
state: {
error: { message: 'some thunk rejected' },
a: { name: '' },
b: { name: '' },
c: { name: '' }
}
thunkA and thunkB are 'rejected' actions, you can handle the rejected action in the errorSlice reducer centralized.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | slideshowp2 |
