You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.5 KiB
51 lines
1.5 KiB
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, AsyncThunkRejectValue {} |
|
|
|
interface RejectedAction extends Action { |
|
payload: AsyncThunkRejectValue; |
|
} |
|
|
|
function isRejectedActionWithPayload( |
|
action: unknown, |
|
): action is RejectedAction { |
|
return isAsyncThunkAction(action) && isRejectedWithValue(action); |
|
} |
|
|
|
function isActionWithmaybeAlertParams( |
|
action: unknown, |
|
): action is ActionWithMaybeAlertParams { |
|
return isAction(action); |
|
} |
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-types -- we need to use `{}` here to ensure the dispatch types can be merged |
|
export const errorsMiddleware: Middleware<{}, RootState> = |
|
({ dispatch }) => |
|
(next) => |
|
(action) => { |
|
if (isRejectedActionWithPayload(action) && !action.payload.skipAlert) { |
|
dispatch( |
|
showAlertForError(action.payload.error, action.payload.skipNotFound), |
|
); |
|
} else if ( |
|
isActionWithmaybeAlertParams(action) && |
|
!action.skipAlert && |
|
action.type.match(isFailedAction) |
|
) { |
|
dispatch(showAlertForError(action.error, action.skipNotFound)); |
|
} |
|
|
|
return next(action); |
|
};
|
|
|