Handle `createAppAsyncThunk` rejected actions in the errors middleware (#29791)

pull/2699/head
Renaud Chaput 2024-03-29 14:57:39 +01:00 committed by GitHub
parent f96648d41c
commit 69e5771881
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 7 deletions

View File

@ -1,16 +1,27 @@
import { isAction } from '@reduxjs/toolkit';
import {
isAction,
isAsyncThunkAction,
isRejectedWithValue,
} from '@reduxjs/toolkit';
import type { Action, Middleware } from '@reduxjs/toolkit';
import type { RootState } from '..';
import { showAlertForError } from '../../actions/alerts';
import type { AsyncThunkRejectValue } from '../typed_functions';
const defaultFailSuffix = 'FAIL';
const isFailedAction = new RegExp(`${defaultFailSuffix}$`, 'g');
interface ActionWithMaybeAlertParams extends Action {
skipAlert?: boolean;
skipNotFound?: boolean;
error?: unknown;
interface ActionWithMaybeAlertParams extends Action, AsyncThunkRejectValue {}
interface RejectedAction extends Action {
payload: AsyncThunkRejectValue;
}
function isRejectedActionWithPayload(
action: unknown,
): action is RejectedAction {
return isAsyncThunkAction(action) && isRejectedWithValue(action);
}
function isActionWithmaybeAlertParams(
@ -23,7 +34,11 @@ export const errorsMiddleware: Middleware<Record<string, never>, RootState> =
({ dispatch }) =>
(next) =>
(action) => {
if (
if (isRejectedActionWithPayload(action) && !action.payload.skipAlert) {
dispatch(
showAlertForError(action.payload.error, action.payload.skipNotFound),
);
} else if (
isActionWithmaybeAlertParams(action) &&
!action.skipAlert &&
action.type.match(isFailedAction)

View File

@ -7,8 +7,14 @@ import type { AppDispatch, RootState } from './store';
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();
export interface AsyncThunkRejectValue {
skipAlert?: boolean;
skipNotFound?: boolean;
error?: unknown;
}
export const createAppAsyncThunk = createAsyncThunk.withTypes<{
state: RootState;
dispatch: AppDispatch;
rejectValue: string;
rejectValue: AsyncThunkRejectValue;
}>();