From eada1eca504703d628b2725f9fdb0ee38ebf81cd Mon Sep 17 00:00:00 2001 From: Richard Yu Date: Mon, 12 Jan 2026 18:38:34 -0800 Subject: [PATCH] refactor: use Zod validation for executionError getter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Export zExecutionErrorWsMessage schema from apiSchema - Use safeParse instead of type casts in TaskItemImpl.executionError - Simplify errorMessage getter to delegate to executionError 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/schemas/apiSchema.ts | 2 +- src/stores/queueStore.ts | 28 ++++++++++------------------ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/schemas/apiSchema.ts b/src/schemas/apiSchema.ts index a77f815aa..11b31841a 100644 --- a/src/schemas/apiSchema.ts +++ b/src/schemas/apiSchema.ts @@ -96,7 +96,7 @@ const zExecutionInterruptedWsMessage = zExecutionWsMessageBase.extend({ node_type: zNodeType, executed: z.array(zNodeId) }) -const zExecutionErrorWsMessage = zExecutionWsMessageBase.extend({ +export const zExecutionErrorWsMessage = zExecutionWsMessageBase.extend({ node_id: zNodeId, node_type: zNodeType, executed: z.array(zNodeId), diff --git a/src/stores/queueStore.ts b/src/stores/queueStore.ts index eb7e3fd5b..cd7572e55 100644 --- a/src/stores/queueStore.ts +++ b/src/stores/queueStore.ts @@ -10,6 +10,7 @@ import type { ComfyWorkflowJSON, NodeId } from '@/platform/workflow/validation/schemas/workflowSchema' +import { zExecutionErrorWsMessage } from '@/schemas/apiSchema' import type { ExecutionErrorWsMessage, HistoryTaskItem, @@ -324,35 +325,26 @@ export class TaskItemImpl { /** * Extracts the execution error message from status messages. * Used by error reporting UI components. - * - * Note: The type cast is required because `messages` is typed as - * `Array<[string, unknown]>` - TypeScript cannot narrow the second tuple - * element's type based on a runtime string check for 'execution_error'. */ get errorMessage(): string | undefined { - const messages = this.status?.messages - if (!Array.isArray(messages) || !messages.length) return undefined - const record = messages.find( - (entry: unknown) => Array.isArray(entry) && entry[0] === 'execution_error' - ) as [string, { exception_message?: string }?] | undefined - return record?.[1]?.exception_message + return this.executionError?.exception_message } /** * Extracts the full execution error from status messages. * Returns the ExecutionErrorWsMessage for detailed error dialogs. - * - * Note: The type cast is required because `messages` is typed as - * `Array<[string, unknown]>` - TypeScript cannot narrow the second tuple - * element's type based on a runtime string check for 'execution_error'. + * Uses Zod validation to ensure type safety. */ get executionError(): ExecutionErrorWsMessage | undefined { const messages = this.status?.messages if (!Array.isArray(messages) || !messages.length) return undefined - const record = messages.find( - (entry: unknown) => Array.isArray(entry) && entry[0] === 'execution_error' - ) as [string, ExecutionErrorWsMessage?] | undefined - return record?.[1] + for (const entry of messages) { + if (entry[0] === 'execution_error') { + const parsed = zExecutionErrorWsMessage.safeParse(entry[1]) + return parsed.success ? parsed.data : undefined + } + } + return undefined } /**