v1.4.25: Actionable generation errors and per-image generation time#384
Conversation
- Classify generation failures into specific, fixable causes (OOM, incompatible VAE, model not in list, missing node, component mismatch) via a centralized classifier; read desktop ComfyUI exception fields so errors no longer surface blank - Longer toast dwell for actionable error messages - Show total generation time in the result preview top-left corner - Show per-image generation time on hover in the session gallery - Add generation.gen_time_label and 6 error keys across all 11 locales
There was a problem hiding this comment.
Code Review
This pull request updates MooshieUI to version 1.4.25, introducing structured generation error classification with actionable feedback and adding a per-image generation-time readout. Key changes include a new error classification utility, localization updates across multiple languages, and state tracking for generation duration. The code review feedback suggests improving TypeScript type safety by passing undefined instead of false to gallery.showToast, utilizing Svelte 5's deep reactivity to directly mutate $state arrays instead of shallow-copying, and making the model filename extraction regex more robust for internationalization and special characters.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| } catch { /* ignore parse errors */ } | ||
| } | ||
| gallery.showToast(toastMsg, "error"); | ||
| gallery.showToast(toastMsg, "error", classified.durationMs ? { durationMs: classified.durationMs } : false); |
There was a problem hiding this comment.
Passing false as the third argument to gallery.showToast violates TypeScript type safety, as the options parameter expects a ToastOptions object or undefined. It should be changed to undefined to ensure type safety and avoid potential compilation or runtime issues.
gallery.showToast(toastMsg, "error", classified.durationMs ? { durationMs: classified.durationMs } : undefined);
| const next = [...this.pendingPrompts]; | ||
| next[idx] = { ...next[idx], startedAt: now }; | ||
| this.pendingPrompts = next; |
There was a problem hiding this comment.
In Svelte 5, $state arrays are deeply reactive by default. Instead of shallow-copying the array and the object to trigger reactivity, you can directly mutate the property of the object in the array. This is more idiomatic, cleaner, and avoids unnecessary object allocations.
| const next = [...this.pendingPrompts]; | |
| next[idx] = { ...next[idx], startedAt: now }; | |
| this.pendingPrompts = next; | |
| this.pendingPrompts[idx].startedAt = now; |
| const m = raw.match(/(\w+):\s*'([^']+)'\s+not in/i); | ||
| if (m) return m[2]; | ||
| // Also handle the node_errors JSON `details` form without quotes. | ||
| const m2 = raw.match(/(?:ckpt_name|vae_name|lora_name|control_net_name|unet_name|clip_name|model_name|upscale_model)[^A-Za-z0-9]+([\w.\- ]+\.(?:safetensors|ckpt|pt|pth|bin|gguf))/i); |
There was a problem hiding this comment.
The regex character class [\w.\- ] does not match non-ASCII characters (such as Chinese, Japanese, or Cyrillic characters) or special characters like parentheses () and brackets [], which are very common in AI model filenames (e.g., downloaded from Civitai). Changing the character class to exclude quotes, newlines, and commas/semicolons ([^'"\r\n,;]+?) makes the filename extraction much more robust and internationalization-friendly.
| const m2 = raw.match(/(?:ckpt_name|vae_name|lora_name|control_net_name|unet_name|clip_name|model_name|upscale_model)[^A-Za-z0-9]+([\w.\- ]+\.(?:safetensors|ckpt|pt|pth|bin|gguf))/i); | |
| const m2 = raw.match(/(?:ckpt_name|vae_name|lora_name|control_net_name|unet_name|clip_name|model_name|upscale_model)[^A-Za-z0-9]+([^'\"\\r\\n,;]+?\\.(?:safetensors|ckpt|pt|pth|bin|gguf))/i); |
|
Triage of the review feedback:
|
What's New in v1.4.25
Clearer error messages
execution_errorpayload has no top-level message field, so the classifier readsexception_message/exception_type/node_type/tracebackinstead.Generation time
Implementation notes
src/lib/utils/generationErrors.ts(pure, testable) used by both theexecution_errorlistener inApp.svelteand the catch path inGenerateButton.svelte.QueuedPrompt(startedAtset insetActivePrompt,durationMscomputed incompletePrompt), threaded throughfinalizeOutputImagesonto eachOutputImage.generationTimeMs.formatGenerationTimehelper inlocaleFormat.ts("12.3s" / "1m 05s").generation.gen_time_labelplus 6 error keys; verified key + placeholder parity across all 11 locales (2057 keys each).Validation
npm run build: passcargo check: pass (compiles as v1.4.25)Bot triage (steps 1-2)