Use new error dialog for queue prompt errors (#3266)

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Chenlei Hu
2025-03-28 13:51:00 -04:00
committed by GitHub
parent 504b717575
commit 04af8cda4d
11 changed files with 87 additions and 51 deletions

View File

@@ -145,6 +145,35 @@ export interface ComfyApi extends EventTarget {
): void
}
export class PromptExecutionError extends Error {
response: PromptResponse
constructor(response: PromptResponse) {
super('Prompt execution failed')
this.response = response
}
override toString() {
let message = super.message
if (typeof this.response.error === 'string') {
message += ': ' + this.response.error
} else if (this.response.error.details) {
message += ': ' + this.response.error.details
}
for (const [_, nodeError] of Object.entries(
this.response.node_errors ?? []
)) {
message += '\n' + nodeError.class_type + ':'
for (const errorReason of nodeError.errors) {
message += '\n - ' + errorReason.message + ': ' + errorReason.details
}
}
return message
}
}
export class ComfyApi extends EventTarget {
#registered = new Set()
api_host: string
@@ -464,9 +493,10 @@ export class ComfyApi extends EventTarget {
}
/**
*
* Queues a prompt to be executed
* @param {number} number The index at which to queue the prompt, passing -1 will insert the prompt at the front of the queue
* @param {object} prompt The prompt data to queue
* @throws {PromptExecutionError} If the prompt fails to execute
*/
async queuePrompt(
number: number,
@@ -496,9 +526,7 @@ export class ComfyApi extends EventTarget {
})
if (res.status !== 200) {
throw {
response: await res.json()
}
throw new PromptExecutionError(await res.json())
}
return await res.json()

View File

@@ -12,7 +12,7 @@ import type { ToastMessageOptions } from 'primevue/toast'
import { reactive } from 'vue'
import { st, t } from '@/i18n'
import type { ResultItem } from '@/schemas/apiSchema'
import type { NodeError, ResultItem } from '@/schemas/apiSchema'
import {
ComfyApiWorkflow,
type ComfyWorkflowJSON,
@@ -47,7 +47,7 @@ import { executeWidgetsCallback, isImageNode } from '@/utils/litegraphUtil'
import { migrateLegacyRerouteNodes } from '@/utils/migration/migrateReroute'
import { deserialiseAndCreate } from '@/utils/vintageClipboard'
import { type ComfyApi, api } from './api'
import { type ComfyApi, PromptExecutionError, api } from './api'
import { defaultGraph } from './defaultGraph'
import {
getFlacMetadata,
@@ -121,7 +121,7 @@ export class ComfyApp {
dragOverNode: LGraphNode | null = null
// @ts-expect-error fixme ts strict error
canvasEl: HTMLCanvasElement
lastNodeErrors: any[] | null = null
lastNodeErrors: Record<NodeId, NodeError> | null = null
/** @type {ExecutionErrorWsMessage} */
lastExecutionError: { node_id?: NodeId } | null = null
configuringGraph: boolean = false
@@ -244,7 +244,7 @@ export class ComfyApp {
}
getPreviewFormatParam() {
let preview_format = this.ui.settings.getSettingValue('Comfy.PreviewFormat')
let preview_format = useSettingStore().get('Comfy.PreviewFormat')
if (preview_format) return `&preview=${preview_format}`
else return ''
}
@@ -570,7 +570,6 @@ export class ComfyApp {
// @ts-expect-error fixme ts strict error
const res = origDrawNodeShape.apply(this, arguments)
// @ts-expect-error fixme ts strict error
const nodeErrors = self.lastNodeErrors?.[node.id]
let color = null
@@ -1223,32 +1222,6 @@ export class ComfyApp {
})
}
// @ts-expect-error fixme ts strict error
#formatPromptError(error) {
if (error == null) {
return '(unknown error)'
} else if (typeof error === 'string') {
return error
} else if (error.stack && error.message) {
return error.toString()
} else if (error.response) {
let message = error.response.error.message
if (error.response.error.details)
message += ': ' + error.response.error.details
for (const [_, nodeError] of Object.entries(error.response.node_errors)) {
// @ts-expect-error
message += '\n' + nodeError.class_type + ':'
// @ts-expect-error
for (const errorReason of nodeError.errors) {
message +=
'\n - ' + errorReason.message + ': ' + errorReason.details
}
}
return message
}
return '(unknown error)'
}
async queuePrompt(number: number, batchCount: number = 1): Promise<boolean> {
this.#queueItems.push({ number, batchCount })
@@ -1287,13 +1260,14 @@ export class ComfyApp {
}
} catch (error) {}
}
} catch (error) {
const formattedError = this.#formatPromptError(error)
this.ui.dialog.show(formattedError)
// @ts-expect-error fixme ts strict error
if (error.response) {
// @ts-expect-error fixme ts strict error
this.lastNodeErrors = error.response.node_errors
} catch (error: unknown) {
useDialogService().showErrorDialog(error, {
title: t('errorDialog.promptExecutionError'),
reportType: 'promptExecutionError'
})
if (error instanceof PromptExecutionError) {
this.lastNodeErrors = error.response.node_errors ?? null
this.canvas.draw(true, true)
}
break