52 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			52 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 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);
 | |
|   };
 |