diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts index fe351f3be6..bdb8e03ad2 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts @@ -76,15 +76,20 @@ 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; } toast({ title: t('queue.batchFailedToQueue'), status: 'error', description: detail, + ...(duration ? { duration } : {}), }); } logger('queue').error( diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts index 814614da10..6cd2056633 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts @@ -1,7 +1,11 @@ import { logger } from 'app/logging/logger'; import { parseify } from 'common/util/serialize'; import { controlNetImageProcessed } from 'features/controlNet/store/actions'; -import { controlNetProcessedImageChanged } from 'features/controlNet/store/controlNetSlice'; +import { + clearPendingControlImages, + controlNetImageChanged, + controlNetProcessedImageChanged, +} from 'features/controlNet/store/controlNetSlice'; import { SAVE_IMAGE } from 'features/nodes/util/graphBuilders/constants'; import { addToast } from 'features/system/store/systemSlice'; import { t } from 'i18next'; @@ -105,8 +109,32 @@ export const addControlNetImageProcessedListener = () => { }) ); } - } catch { + } catch (error) { log.error({ graph: parseify(graph) }, 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(clearPendingControlImages()); + dispatch( + controlNetImageChanged({ controlNetId, controlImage: null }) + ); + return; + } + } + } + dispatch( addToast({ title: t('queue.graphFailedToQueue'), diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts index b54d8b553c..cad6c341f1 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts @@ -44,8 +44,28 @@ export const addUpscaleRequestedListener = () => { { enqueueResult: parseify(enqueueResult) }, t('queue.graphQueued') ); - } catch { + } catch (error) { log.error({ graph: parseify(graph) }, 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; + } + } + } + dispatch( addToast({ title: t('queue.graphFailedToQueue'), diff --git a/invokeai/frontend/web/src/features/controlNet/store/controlNetSlice.ts b/invokeai/frontend/web/src/features/controlNet/store/controlNetSlice.ts index f0745eae2b..9b5dec68f3 100644 --- a/invokeai/frontend/web/src/features/controlNet/store/controlNetSlice.ts +++ b/invokeai/frontend/web/src/features/controlNet/store/controlNetSlice.ts @@ -410,6 +410,9 @@ export const controlNetSlice = createSlice({ state.isIPAdapterEnabled = false; state.ipAdapterInfo = { ...initialIPAdapterState }; }, + clearPendingControlImages: (state) => { + state.pendingControlImages = []; + }, }, extraReducers: (builder) => { builder.addCase(controlNetImageProcessed, (state, action) => { @@ -474,6 +477,7 @@ export const { ipAdapterBeginStepPctChanged, ipAdapterEndStepPctChanged, ipAdapterStateReset, + clearPendingControlImages, } = controlNetSlice.actions; export default controlNetSlice.reducer;