mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-06-08 23:39:23 +00:00
## Summary This is the first PR in a planned stack to modernize the Workflow Overview error tab. It focuses only on execution-style errors: validation errors, runtime errors, and known prompt errors. The intent is to establish the catalog-driven presentation model before touching the larger missing-resource cards. Validation and prompt errors are known product states, so this PR makes them read more like structured guidance instead of generic reportable failures. Runtime errors remain reportable, but their details are reorganized so the error log is easier to scan and copy. ## What changed - Groups validation errors by error catalog id instead of node class/type. - Adds an `unknown_validation_error` fallback catalog id so validation grouping can follow one rule without special-case missing catalog ids. - Shows validation group title and message once, then lists each affected input as a compact item row. - Adds per-item validation detail disclosure so detailed validation text is still available without repeating the group title/message for every item. - Keeps locate-node behavior available from validation rows, including keyboard/ARIA disclosure wiring. - Removes GitHub, copy, and help actions from validation/prompt errors because these are known, cataloged errors where the UI copy should guide the user directly. - Refines runtime error cards so the error log is visible by default, has its own header, and keeps copy/report actions inside the log area. - Removes the special full-panel singleton runtime layout so runtime errors keep the same fixed card rhythm as the other error groups. - Keeps runtime errors reportable via Get Help and Find on GitHub, because these can still represent unexpected execution failures. - Updates prompt error detail styling to match the darker runtime error-log treatment. - Restores display-message semantics for grouped execution messages: `displayMessage ?? message` is used for user-facing dedupe instead of raw backend-only messages. - Adds focused unit coverage for catalog grouping, fallback validation catalog ids, display-message grouping, runtime detail behavior, and the updated prompt/validation action model. ## Planned stack This PR intentionally keeps the first slice narrow. The broader redesign is planned as a sequence of follow-up PRs rather than one large change: 1. Execution errors, this PR: validation, runtime, and prompt error grouping/presentation. 2. Missing media: simplify image/video/audio missing-media cards around catalog item labels and locate actions. 3. Missing node and swap node: align missing-pack rows, nested node references, install/replace actions, and locate behavior. 4. Missing model: unify OSS and Cloud presentation, simplify download/import actions, and improve import/download progress behavior. The goal is to review and stabilize each slice before stacking the next one. This is especially important because later missing-model changes are much larger and should not obscure the catalog/error-card behavior introduced here. ## Review focus - Validation errors should now group by catalog id, not by node class. - Validation groups intentionally show one message per group, with individual affected inputs rendered as rows. - Prompt and validation errors intentionally no longer show report/copy/help actions. - Runtime errors intentionally still show report actions, but only inside the error-log panel. - Node id badges are intentionally not shown in these execution error rows; the follow-up missing-resource PRs will handle their own row treatments separately. - This PR does not change missing media, missing model, missing node pack, or swap node cards. ## Screenshots ### This PR Validation error <img width="457" height="362" alt="스크린샷 2026-06-07 오전 4 26 19" src="https://github.com/user-attachments/assets/4c35b9f3-57dd-4dae-b44a-6d2fd8547b7c" /> Runtime error <img width="454" height="545" alt="스크린샷 2026-06-07 오전 4 24 24" src="https://github.com/user-attachments/assets/b7d4482f-b35b-4ed2-90f2-0a62dafa3519" /> Prompt / Service error <img width="456" height="192" alt="스크린샷 2026-06-07 오전 4 27 58" src="https://github.com/user-attachments/assets/aeec0978-b47f-40c7-ab71-0a0d18ceb054" /> ### Old (main) Validation error <img width="457" height="853" alt="스크린샷 2026-06-07 오전 4 25 09" src="https://github.com/user-attachments/assets/185dd573-430d-4041-8b31-a8eb6346f1ff" /> Runtime error <img width="455" height="554" alt="스크린샷 2026-06-07 오전 4 24 58" src="https://github.com/user-attachments/assets/deb1c09d-ea58-4d6a-9ac6-d2a3a9832fbe" /> Prompt / Service error <img width="455" height="297" alt="스크린샷 2026-06-07 오전 4 28 14" src="https://github.com/user-attachments/assets/c68eef7c-6525-4a5b-858c-6482fe76ad27" /> ## Validation - `pnpm format:check` - `pnpm test:unit src/components/rightSidePanel/errors/TabErrors.test.ts src/components/rightSidePanel/errors/ErrorNodeCard.test.ts src/components/rightSidePanel/errors/useErrorGroups.test.ts src/platform/errorCatalog/errorMessageResolver.test.ts` - `pnpm typecheck` - `pnpm lint` - `pnpm knip` - `pnpm build`
133 lines
2.8 KiB
TypeScript
133 lines
2.8 KiB
TypeScript
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
|
import ErrorNodeCard from './ErrorNodeCard.vue'
|
|
import type { ErrorCardData } from './types'
|
|
|
|
const meta: Meta<typeof ErrorNodeCard> = {
|
|
title: 'RightSidePanel/Errors/ErrorNodeCard',
|
|
component: ErrorNodeCard,
|
|
parameters: {
|
|
layout: 'centered'
|
|
},
|
|
decorators: [
|
|
(story) => ({
|
|
components: { story },
|
|
template:
|
|
'<div class="w-[330px] bg-base-surface border border-interface-stroke rounded-lg p-4"><story /></div>'
|
|
})
|
|
]
|
|
}
|
|
|
|
export default meta
|
|
type Story = StoryObj<typeof meta>
|
|
|
|
const singleErrorCard: ErrorCardData = {
|
|
id: 'node-10',
|
|
title: 'CLIPTextEncode',
|
|
nodeId: '10',
|
|
nodeTitle: 'CLIP Text Encode (Prompt)',
|
|
isSubgraphNode: false,
|
|
errors: [
|
|
{
|
|
message: 'Required input "text" is missing.',
|
|
details: 'Input: text\nExpected: STRING'
|
|
}
|
|
]
|
|
}
|
|
|
|
const multipleErrorsCard: ErrorCardData = {
|
|
id: 'node-24',
|
|
title: 'VAEDecode',
|
|
nodeId: '24',
|
|
nodeTitle: 'VAE Decode',
|
|
isSubgraphNode: false,
|
|
errors: [
|
|
{
|
|
message: 'Required input "samples" is missing.',
|
|
details: ''
|
|
},
|
|
{
|
|
message: 'Value "NaN" is not a valid number for "strength".',
|
|
details: 'Expected: FLOAT [0.0 .. 1.0]'
|
|
}
|
|
]
|
|
}
|
|
|
|
const runtimeErrorCard: ErrorCardData = {
|
|
id: 'exec-45',
|
|
title: 'KSampler',
|
|
nodeId: '45',
|
|
nodeTitle: 'KSampler',
|
|
isSubgraphNode: false,
|
|
errors: [
|
|
{
|
|
message: 'OutOfMemoryError: CUDA out of memory. Tried to allocate 1.2GB.',
|
|
details: [
|
|
'Traceback (most recent call last):',
|
|
' File "ksampler.py", line 142, in sample',
|
|
' samples = model.apply(latent)',
|
|
'RuntimeError: CUDA out of memory.'
|
|
].join('\n'),
|
|
isRuntimeError: true
|
|
}
|
|
]
|
|
}
|
|
|
|
const subgraphErrorCard: ErrorCardData = {
|
|
id: 'node-3:15',
|
|
title: 'KSampler',
|
|
nodeId: '3:15',
|
|
nodeTitle: 'Nested KSampler',
|
|
isSubgraphNode: true,
|
|
errors: [
|
|
{
|
|
message: 'Latent input is required.',
|
|
details: ''
|
|
}
|
|
]
|
|
}
|
|
|
|
const promptOnlyCard: ErrorCardData = {
|
|
id: '__prompt__',
|
|
title: 'Prompt has no outputs.',
|
|
errors: [
|
|
{
|
|
message:
|
|
'The workflow does not contain any output nodes (e.g. Save Image, Preview Image) to produce a result.'
|
|
}
|
|
]
|
|
}
|
|
|
|
export const SingleValidationError: Story = {
|
|
args: {
|
|
card: singleErrorCard
|
|
}
|
|
}
|
|
|
|
/** Subgraph node error — shows "Enter subgraph" button */
|
|
export const WithEnterSubgraphButton: Story = {
|
|
args: {
|
|
card: subgraphErrorCard
|
|
}
|
|
}
|
|
|
|
/** Multiple validation errors on one node */
|
|
export const MultipleErrors: Story = {
|
|
args: {
|
|
card: multipleErrorsCard
|
|
}
|
|
}
|
|
|
|
/** Runtime execution error with full traceback */
|
|
export const RuntimeError: Story = {
|
|
args: {
|
|
card: runtimeErrorCard
|
|
}
|
|
}
|
|
|
|
/** Prompt-level error (no node header) */
|
|
export const PromptError: Story = {
|
|
args: {
|
|
card: promptOnlyCard
|
|
}
|
|
}
|