mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-01-18 06:28:09 -05:00
Compare commits
1 Commits
controlnet
...
maryhipp/t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2259157231 |
@@ -1,6 +1,7 @@
|
||||
import { logger } from 'app/logging/logger';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { truncate } from 'es-toolkit/compat';
|
||||
import { trackErrorDetails } from 'features/system/store/actions';
|
||||
import { zPydanticValidationError } from 'features/system/store/zodSchemas';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
@@ -34,7 +35,7 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
|
||||
// error
|
||||
startAppListening({
|
||||
matcher: queueApi.endpoints.enqueueBatch.matchRejected,
|
||||
effect: (action) => {
|
||||
effect: (action, { dispatch }) => {
|
||||
const response = action.payload;
|
||||
const batchConfig = action.meta.arg.originalArgs;
|
||||
|
||||
@@ -46,6 +47,13 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
|
||||
description: t('common.unknownError'),
|
||||
});
|
||||
log.error({ batchConfig } as JsonObject, t('queue.batchFailedToQueue'));
|
||||
dispatch(
|
||||
trackErrorDetails({
|
||||
title: 'Enqueue Batch Rejected',
|
||||
errorMessage: t('common.unknownError'),
|
||||
description: null,
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,6 +67,9 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
|
||||
status: 'error',
|
||||
description,
|
||||
});
|
||||
dispatch(
|
||||
trackErrorDetails({ title: 'Enqueue Batch Rejected', errorMessage: e.msg, description: description })
|
||||
);
|
||||
});
|
||||
} else if (response.status !== 403) {
|
||||
toast({
|
||||
@@ -69,6 +80,13 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
|
||||
});
|
||||
}
|
||||
log.error({ batchConfig, error: serializeError(response) } as JsonObject, t('queue.batchFailedToQueue'));
|
||||
dispatch(
|
||||
trackErrorDetails({
|
||||
title: 'Enqueue Batch Rejected',
|
||||
errorMessage: t('common.unknownError'),
|
||||
description: null,
|
||||
})
|
||||
);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -6,6 +6,8 @@ import { omit } from 'es-toolkit/compat';
|
||||
import { imageUploadedClientSide } from 'features/gallery/store/actions';
|
||||
import { selectListBoardsQueryArgs } from 'features/gallery/store/gallerySelectors';
|
||||
import { boardIdSelected, galleryViewChanged } from 'features/gallery/store/gallerySlice';
|
||||
import { trackErrorDetails } from 'features/system/store/actions';
|
||||
import { zPydanticValidationErrorWithDetail } from 'features/system/store/zodSchemas';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { boardsApi } from 'services/api/endpoints/boards';
|
||||
@@ -130,7 +132,7 @@ export const addImageUploadedFulfilledListener = (startAppListening: AppStartLis
|
||||
|
||||
startAppListening({
|
||||
matcher: imagesApi.endpoints.uploadImage.matchRejected,
|
||||
effect: (action) => {
|
||||
effect: (action, { dispatch }) => {
|
||||
const sanitizedData = {
|
||||
arg: {
|
||||
...omit(action.meta.arg.originalArgs, ['file', 'postUploadAction']),
|
||||
@@ -138,9 +140,15 @@ export const addImageUploadedFulfilledListener = (startAppListening: AppStartLis
|
||||
},
|
||||
};
|
||||
log.error({ ...sanitizedData }, 'Image upload failed');
|
||||
|
||||
const parsedError = zPydanticValidationErrorWithDetail.safeParse(action.payload);
|
||||
const errorMessage = parsedError.success ? parsedError.data.data.detail : action.error.message;
|
||||
|
||||
dispatch(trackErrorDetails({ title: 'Image Upload Rejected', errorMessage, description: null }));
|
||||
|
||||
toast({
|
||||
title: t('toast.imageUploadFailed'),
|
||||
description: action.error.message,
|
||||
description: errorMessage,
|
||||
status: 'error',
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import type { ButtonProps, IconButtonProps, SystemStyleObject } from '@invoke-ai/ui-library';
|
||||
import { Button, IconButton } from '@invoke-ai/ui-library';
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectAutoAddBoardId } from 'features/gallery/store/gallerySelectors';
|
||||
import { trackErrorDetails } from 'features/system/store/actions';
|
||||
import { selectIsClientSideUploadEnabled } from 'features/system/store/configSlice';
|
||||
import { zPydanticValidationErrorWithDetail } from 'features/system/store/zodSchemas';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { memo, useCallback } from 'react';
|
||||
import type { FileRejection } from 'react-dropzone';
|
||||
@@ -65,6 +67,7 @@ export const useImageUploadButton = ({
|
||||
const [uploadImage, request] = useUploadImageMutation();
|
||||
const clientSideUpload = useClientSideUpload();
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const onDropAccepted = useCallback(
|
||||
async (files: File[]) => {
|
||||
@@ -116,6 +119,11 @@ export const useImageUploadButton = ({
|
||||
}
|
||||
} catch (error) {
|
||||
onError?.(error);
|
||||
const parsedError = zPydanticValidationErrorWithDetail.safeParse(error);
|
||||
const errorMessage = parsedError.success ? parsedError.data.data.detail : undefined;
|
||||
|
||||
dispatch(trackErrorDetails({ title: 'Failed to upload image', errorMessage, description: null }));
|
||||
|
||||
toast({
|
||||
id: 'UPLOAD_FAILED',
|
||||
title: t('toast.imageUploadFailed'),
|
||||
@@ -133,6 +141,7 @@ export const useImageUploadButton = ({
|
||||
clientSideUpload,
|
||||
onError,
|
||||
t,
|
||||
dispatch,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { $projectUrl } from 'app/store/nanostores/projectId';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||
import { withResultAsync } from 'common/util/result';
|
||||
import { parseify } from 'common/util/serialize';
|
||||
@@ -40,6 +40,7 @@ import { useOutputFieldTemplate } from 'features/nodes/hooks/useOutputFieldTempl
|
||||
import { useZoomToNode } from 'features/nodes/hooks/useZoomToNode';
|
||||
import { useEnqueueWorkflows } from 'features/queue/hooks/useEnqueueWorkflows';
|
||||
import { $isReadyToEnqueue } from 'features/queue/store/readiness';
|
||||
import { trackErrorDetails } from 'features/system/store/actions';
|
||||
import { selectAllowPublishWorkflows } from 'features/system/store/configSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
@@ -209,6 +210,7 @@ const PublishWorkflowButton = memo(() => {
|
||||
const isSelectingOutputNode = useStore($isSelectingOutputNode);
|
||||
const inputs = usePublishInputs();
|
||||
const allowPublishWorkflows = useAppSelector(selectAllowPublishWorkflows);
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const projectUrl = useStore($projectUrl);
|
||||
|
||||
@@ -217,6 +219,9 @@ const PublishWorkflowButton = memo(() => {
|
||||
$isPublishing.set(true);
|
||||
const result = await withResultAsync(() => enqueue(true, true));
|
||||
if (result.isErr()) {
|
||||
dispatch(
|
||||
trackErrorDetails({ title: 'Failed to enqueue batch', errorMessage: result.error.message, description: null })
|
||||
);
|
||||
toast({
|
||||
id: 'TOAST_PUBLISH_FAILED',
|
||||
status: 'error',
|
||||
@@ -225,6 +230,13 @@ const PublishWorkflowButton = memo(() => {
|
||||
duration: null,
|
||||
});
|
||||
log.error({ error: serializeError(result.error) }, 'Failed to enqueue batch');
|
||||
dispatch(
|
||||
trackErrorDetails({
|
||||
title: 'Failed to enqueue batch',
|
||||
errorMessage: serializeError(result.error).message,
|
||||
description: serializeError(result.error).stack?.toString() ?? null,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
toast({
|
||||
id: 'TOAST_PUBLISH_SUCCESSFUL',
|
||||
@@ -249,7 +261,7 @@ const PublishWorkflowButton = memo(() => {
|
||||
log.debug(parseify(result.value), 'Enqueued batch');
|
||||
}
|
||||
$isPublishing.set(false);
|
||||
}, [enqueue, projectUrl, t]);
|
||||
}, [enqueue, projectUrl, t, dispatch]);
|
||||
|
||||
const isDisabled = useMemo(() => {
|
||||
return (
|
||||
|
||||
@@ -21,6 +21,7 @@ import { buildSD3Graph } from 'features/nodes/util/graph/generation/buildSD3Grap
|
||||
import { buildSDXLGraph } from 'features/nodes/util/graph/generation/buildSDXLGraph';
|
||||
import type { GraphBuilderArg } from 'features/nodes/util/graph/types';
|
||||
import { UnsupportedGenerationModeError } from 'features/nodes/util/graph/types';
|
||||
import { trackErrorDetails } from 'features/system/store/actions';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import { serializeError } from 'serialize-error';
|
||||
@@ -89,6 +90,7 @@ const enqueueCanvas = async (store: AppStore, canvasManager: CanvasManager, prep
|
||||
}
|
||||
const error = serializeError(buildGraphResult.error);
|
||||
log.error({ error }, 'Failed to build graph');
|
||||
dispatch(trackErrorDetails({ title, errorMessage: error.message, description }));
|
||||
toast({
|
||||
status,
|
||||
title,
|
||||
|
||||
@@ -19,6 +19,7 @@ import { buildSD3Graph } from 'features/nodes/util/graph/generation/buildSD3Grap
|
||||
import { buildSDXLGraph } from 'features/nodes/util/graph/generation/buildSDXLGraph';
|
||||
import type { GraphBuilderArg } from 'features/nodes/util/graph/types';
|
||||
import { UnsupportedGenerationModeError } from 'features/nodes/util/graph/types';
|
||||
import { trackErrorDetails } from 'features/system/store/actions';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import { serializeError } from 'serialize-error';
|
||||
@@ -86,6 +87,7 @@ const enqueueGenerate = async (store: AppStore, prepend: boolean) => {
|
||||
status = 'warning';
|
||||
}
|
||||
const error = serializeError(buildGraphResult.error);
|
||||
dispatch(trackErrorDetails({ title, errorMessage: error.message, description }));
|
||||
log.error({ error }, 'Failed to build graph');
|
||||
toast({
|
||||
status,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { withResultAsync } from 'common/util/result';
|
||||
import { useIsWorkflowEditorLocked } from 'features/nodes/hooks/useIsWorkflowEditorLocked';
|
||||
import { useEnqueueWorkflows } from 'features/queue/hooks/useEnqueueWorkflows';
|
||||
import { $isReadyToEnqueue } from 'features/queue/store/readiness';
|
||||
import { trackErrorDetails } from 'features/system/store/actions';
|
||||
import { navigationApi } from 'features/ui/layouts/navigation-api';
|
||||
import { VIEWER_PANEL_ID, WORKSPACE_PANEL_ID } from 'features/ui/layouts/shared';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
@@ -26,6 +27,7 @@ export const useInvoke = () => {
|
||||
const enqueueCanvas = useEnqueueCanvas();
|
||||
const enqueueGenerate = useEnqueueGenerate();
|
||||
const enqueueUpscaling = useEnqueueUpscaling();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [_, { isLoading }] = useEnqueueBatchMutation({
|
||||
...enqueueMutationFixedCacheKeyOptions,
|
||||
@@ -55,9 +57,16 @@ export const useInvoke = () => {
|
||||
|
||||
if (result.isErr()) {
|
||||
log.error({ error: serializeError(result.error) }, 'Failed to enqueue batch');
|
||||
dispatch(
|
||||
trackErrorDetails({
|
||||
title: 'Failed to enqueue batch',
|
||||
errorMessage: serializeError(result.error).message,
|
||||
description: serializeError(result.error).stack?.toString() ?? null,
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
[enqueueCanvas, enqueueGenerate, enqueueUpscaling, enqueueWorkflows, isReady, tabName]
|
||||
[enqueueCanvas, enqueueGenerate, enqueueUpscaling, enqueueWorkflows, isReady, tabName, dispatch]
|
||||
);
|
||||
|
||||
const enqueueBack = useCallback(() => {
|
||||
|
||||
@@ -2,3 +2,9 @@ import { createAction } from '@reduxjs/toolkit';
|
||||
|
||||
export const videoModalLinkClicked = createAction<string>('system/videoModalLinkClicked');
|
||||
export const videoModalOpened = createAction('system/videoModalOpened');
|
||||
|
||||
export const trackErrorDetails = createAction<{
|
||||
title: string;
|
||||
errorMessage?: string;
|
||||
description: string | null;
|
||||
}>('system/trackErrorDetails');
|
||||
|
||||
@@ -12,3 +12,9 @@ export const zPydanticValidationError = z.object({
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
export const zPydanticValidationErrorWithDetail = z.object({
|
||||
data: z.object({
|
||||
detail: z.string(),
|
||||
}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user