Commit 1cfb2a73 authored by comfyanonymous's avatar comfyanonymous
Browse files

Merge branch 'error-improvements' of https://github.com/space-nuko/ComfyUI

parents 00646b08 03f2d0a7
This diff is collapsed.
...@@ -88,6 +88,12 @@ class ComfyApi extends EventTarget { ...@@ -88,6 +88,12 @@ class ComfyApi extends EventTarget {
case "executed": case "executed":
this.dispatchEvent(new CustomEvent("executed", { detail: msg.data })); this.dispatchEvent(new CustomEvent("executed", { detail: msg.data }));
break; break;
case "execution_start":
this.dispatchEvent(new CustomEvent("execution_start", { detail: msg.data }));
break;
case "execution_error":
this.dispatchEvent(new CustomEvent("execution_error", { detail: msg.data }));
break;
default: default:
if (this.#registered.has(msg.type)) { if (this.#registered.has(msg.type)) {
this.dispatchEvent(new CustomEvent(msg.type, { detail: msg.data })); this.dispatchEvent(new CustomEvent(msg.type, { detail: msg.data }));
......
...@@ -771,16 +771,27 @@ export class ComfyApp { ...@@ -771,16 +771,27 @@ export class ComfyApp {
LGraphCanvas.prototype.drawNodeShape = function (node, ctx, size, fgcolor, bgcolor, selected, mouse_over) { LGraphCanvas.prototype.drawNodeShape = function (node, ctx, size, fgcolor, bgcolor, selected, mouse_over) {
const res = origDrawNodeShape.apply(this, arguments); const res = origDrawNodeShape.apply(this, arguments);
const nodeErrors = self.lastPromptError?.node_errors[node.id];
let color = null; let color = null;
let lineWidth = 1;
if (node.id === +self.runningNodeId) { if (node.id === +self.runningNodeId) {
color = "#0f0"; color = "#0f0";
} else if (self.dragOverNode && node.id === self.dragOverNode.id) { } else if (self.dragOverNode && node.id === self.dragOverNode.id) {
color = "dodgerblue"; color = "dodgerblue";
} }
else if (self.lastPromptError != null && nodeErrors?.errors) {
color = "red";
lineWidth = 2;
}
else if (self.lastExecutionError && +self.lastExecutionError.node_id === node.id) {
color = "#f0f";
lineWidth = 2;
}
if (color) { if (color) {
const shape = node._shape || node.constructor.shape || LiteGraph.ROUND_SHAPE; const shape = node._shape || node.constructor.shape || LiteGraph.ROUND_SHAPE;
ctx.lineWidth = 1; ctx.lineWidth = lineWidth;
ctx.globalAlpha = 0.8; ctx.globalAlpha = 0.8;
ctx.beginPath(); ctx.beginPath();
if (shape == LiteGraph.BOX_SHAPE) if (shape == LiteGraph.BOX_SHAPE)
...@@ -807,11 +818,28 @@ export class ComfyApp { ...@@ -807,11 +818,28 @@ export class ComfyApp {
ctx.stroke(); ctx.stroke();
ctx.strokeStyle = fgcolor; ctx.strokeStyle = fgcolor;
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
}
if (self.progress) { if (self.progress && node.id === +self.runningNodeId) {
ctx.fillStyle = "green"; ctx.fillStyle = "green";
ctx.fillRect(0, 0, size[0] * (self.progress.value / self.progress.max), 6); ctx.fillRect(0, 0, size[0] * (self.progress.value / self.progress.max), 6);
ctx.fillStyle = bgcolor; ctx.fillStyle = bgcolor;
}
// Highlight inputs that failed validation
if (nodeErrors) {
ctx.lineWidth = 2;
ctx.strokeStyle = "red";
for (const error of nodeErrors.errors) {
if (error.extra_info && error.extra_info.input_name) {
const inputIndex = node.findInputSlot(error.extra_info.input_name)
if (inputIndex !== -1) {
let pos = node.getConnectionPos(true, inputIndex);
ctx.beginPath();
ctx.arc(pos[0] - node.pos[0], pos[1] - node.pos[1], 12, 0, 2 * Math.PI, false)
ctx.stroke();
}
}
} }
} }
...@@ -869,6 +897,17 @@ export class ComfyApp { ...@@ -869,6 +897,17 @@ export class ComfyApp {
} }
}); });
api.addEventListener("execution_start", ({ detail }) => {
this.lastExecutionError = null
});
api.addEventListener("execution_error", ({ detail }) => {
this.lastExecutionError = detail;
const formattedError = this.#formatExecutionError(detail);
this.ui.dialog.show(formattedError);
this.canvas.draw(true, true);
});
api.init(); api.init();
} }
...@@ -1243,6 +1282,43 @@ export class ComfyApp { ...@@ -1243,6 +1282,43 @@ export class ComfyApp {
return { workflow, output }; return { workflow, output };
} }
#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 [nodeID, nodeError] of Object.entries(error.response.node_errors)) {
message += "\n" + nodeError.class_type + ":"
for (const errorReason of nodeError.errors) {
message += "\n - " + errorReason.message + ": " + errorReason.details
}
}
return message
}
return "(unknown error)"
}
#formatExecutionError(error) {
if (error == null) {
return "(unknown error)"
}
const traceback = error.traceback.join("")
const nodeId = error.node_id
const nodeType = error.node_type
return `Error occurred when executing ${nodeType}:\n\n${error.message}\n\n${traceback}`
}
async queuePrompt(number, batchCount = 1) { async queuePrompt(number, batchCount = 1) {
this.#queueItems.push({ number, batchCount }); this.#queueItems.push({ number, batchCount });
...@@ -1250,8 +1326,10 @@ export class ComfyApp { ...@@ -1250,8 +1326,10 @@ export class ComfyApp {
if (this.#processingQueue) { if (this.#processingQueue) {
return; return;
} }
this.#processingQueue = true; this.#processingQueue = true;
this.lastPromptError = null;
try { try {
while (this.#queueItems.length) { while (this.#queueItems.length) {
({ number, batchCount } = this.#queueItems.pop()); ({ number, batchCount } = this.#queueItems.pop());
...@@ -1262,7 +1340,12 @@ export class ComfyApp { ...@@ -1262,7 +1340,12 @@ export class ComfyApp {
try { try {
await api.queuePrompt(number, p); await api.queuePrompt(number, p);
} catch (error) { } catch (error) {
this.ui.dialog.show(error.response.error || error.toString()); const formattedError = this.#formatPromptError(error)
this.ui.dialog.show(formattedError);
if (error.response) {
this.lastPromptError = error.response;
this.canvas.draw(true, true);
}
break; break;
} }
...@@ -1360,6 +1443,8 @@ export class ComfyApp { ...@@ -1360,6 +1443,8 @@ export class ComfyApp {
*/ */
clean() { clean() {
this.nodeOutputs = {}; this.nodeOutputs = {};
this.lastPromptError = null;
this.lastExecutionError = null;
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment