mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
add middleware to handle 403 errors (#5245)
* add middleware to handle 403 errors * remove log * add logic to warn the user if not all requested images could be deleted * lint * fix copy * feat(ui): simplify batchEnqueuedListener error toast logic * feat(ui): use translations for error messages * chore(ui): lint --------- Co-authored-by: Mary Hipp <maryhipp@Marys-MacBook-Air.local> Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
This commit is contained in:
parent
db58efbe65
commit
b519b6e1e0
@ -161,6 +161,7 @@
|
||||
"txt2img": "Text To Image",
|
||||
"unifiedCanvas": "Unified Canvas",
|
||||
"unknown": "Unknown",
|
||||
"unknownError": "Unknown Error",
|
||||
"upload": "Upload"
|
||||
},
|
||||
"controlnet": {
|
||||
@ -384,7 +385,9 @@
|
||||
"deleteSelection": "Delete Selection",
|
||||
"downloadSelection": "Download Selection",
|
||||
"preparingDownload": "Preparing Download",
|
||||
"preparingDownloadFailed": "Problem Preparing Download"
|
||||
"preparingDownloadFailed": "Problem Preparing Download",
|
||||
"problemDeletingImages": "Problem Deleting Images",
|
||||
"problemDeletingImagesDesc": "One or more images could not be deleted"
|
||||
},
|
||||
"hotkeys": {
|
||||
"acceptStagingImage": {
|
||||
|
@ -3,7 +3,7 @@ import { logger } from 'app/logging/logger';
|
||||
import { parseify } from 'common/util/serialize';
|
||||
import { zPydanticValidationError } from 'features/system/store/zodSchemas';
|
||||
import { t } from 'i18next';
|
||||
import { get, truncate, upperFirst } from 'lodash-es';
|
||||
import { truncate, upperFirst } from 'lodash-es';
|
||||
import { queueApi } from 'services/api/endpoints/queue';
|
||||
import { TOAST_OPTIONS, theme } from 'theme/theme';
|
||||
import { startAppListening } from '..';
|
||||
@ -74,22 +74,11 @@ export const addBatchEnqueuedListener = () => {
|
||||
),
|
||||
});
|
||||
});
|
||||
} else {
|
||||
let detail = 'Unknown Error';
|
||||
let duration = undefined;
|
||||
if (response.status === 403 && 'body' in response) {
|
||||
detail = get(response, 'body.detail', 'Unknown Error');
|
||||
} else if (response.status === 403 && 'error' in response) {
|
||||
detail = get(response, 'error.detail', 'Unknown Error');
|
||||
} else if (response.status === 403 && 'data' in response) {
|
||||
detail = get(response, 'data.detail', 'Unknown Error');
|
||||
duration = 15000;
|
||||
}
|
||||
} else if (response.status !== 403) {
|
||||
toast({
|
||||
title: t('queue.batchFailedToQueue'),
|
||||
description: t('common.unknownError'),
|
||||
status: 'error',
|
||||
description: detail,
|
||||
...(duration ? { duration } : {}),
|
||||
});
|
||||
}
|
||||
logger('queue').error(
|
||||
|
@ -109,20 +109,9 @@ export const addControlNetImageProcessedListener = () => {
|
||||
t('queue.graphFailedToQueue')
|
||||
);
|
||||
|
||||
// handle usage-related errors
|
||||
if (error instanceof Object) {
|
||||
if ('data' in error && 'status' in error) {
|
||||
if (error.status === 403) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const detail = (error.data as any)?.detail || 'Unknown Error';
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
description: detail,
|
||||
duration: 15000,
|
||||
})
|
||||
);
|
||||
dispatch(pendingControlImagesCleared());
|
||||
dispatch(controlAdapterImageChanged({ id, controlImage: null }));
|
||||
return;
|
||||
|
@ -75,31 +75,20 @@ export const addUpscaleRequestedListener = () => {
|
||||
t('queue.graphFailedToQueue')
|
||||
);
|
||||
|
||||
// handle usage-related errors
|
||||
if (error instanceof Object) {
|
||||
if ('data' in error && 'status' in error) {
|
||||
if (error.status === 403) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const detail = (error.data as any)?.detail || 'Unknown Error';
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
description: detail,
|
||||
duration: 15000,
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (
|
||||
error instanceof Object &&
|
||||
'status' in error &&
|
||||
error.status === 403
|
||||
) {
|
||||
return;
|
||||
} else {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -33,6 +33,7 @@ import { actionsDenylist } from './middleware/devtools/actionsDenylist';
|
||||
import { stateSanitizer } from './middleware/devtools/stateSanitizer';
|
||||
import { listenerMiddleware } from './middleware/listenerMiddleware';
|
||||
import { createStore as createIDBKeyValStore, get, set } from 'idb-keyval';
|
||||
import { authToastMiddleware } from 'services/api/authToastMiddleware';
|
||||
|
||||
const allReducers = {
|
||||
canvas: canvasReducer,
|
||||
@ -107,6 +108,7 @@ export const createStore = (uniqueStoreKey?: string) =>
|
||||
})
|
||||
.concat(api.middleware)
|
||||
.concat(dynamicMiddlewares)
|
||||
.concat(authToastMiddleware)
|
||||
.prepend(listenerMiddleware.middleware),
|
||||
devTools: {
|
||||
actionSanitizer,
|
||||
|
@ -0,0 +1,26 @@
|
||||
import { isRejectedWithValue } from '@reduxjs/toolkit';
|
||||
import type { MiddlewareAPI, Middleware } from '@reduxjs/toolkit';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { t } from 'i18next';
|
||||
|
||||
export const authToastMiddleware: Middleware =
|
||||
(api: MiddlewareAPI) => (next) => (action) => {
|
||||
if (isRejectedWithValue(action)) {
|
||||
if (action.payload.status === 403) {
|
||||
const { dispatch } = api;
|
||||
const customMessage =
|
||||
action.payload.data.detail !== 'Forbidden'
|
||||
? action.payload.data.detail
|
||||
: undefined;
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('common.somethingWentWrong'),
|
||||
status: 'error',
|
||||
description: customMessage,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return next(action);
|
||||
};
|
@ -27,6 +27,8 @@ import {
|
||||
imagesSelectors,
|
||||
} from 'services/api/util';
|
||||
import { boardsApi } from './boards';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { t } from 'i18next';
|
||||
|
||||
export const imagesApi = api.injectEndpoints({
|
||||
endpoints: (build) => ({
|
||||
@ -208,6 +210,16 @@ export const imagesApi = api.injectEndpoints({
|
||||
try {
|
||||
const { data } = await queryFulfilled;
|
||||
|
||||
if (data.deleted_images.length < imageDTOs.length) {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('gallery.problemDeletingImages'),
|
||||
description: t('gallery.problemDeletingImagesDesc'),
|
||||
status: 'warning',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// convert to an object so we can access the successfully delete image DTOs by name
|
||||
const groupedImageDTOs = keyBy(imageDTOs, 'image_name');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user