[refactor] Extract executionErrorStore from executionStore (#9060)

## Summary
Extracts error-related state and logic from `executionStore` into a
dedicated `executionErrorStore` for better separation of concerns.

## Changes
- **New store**: `executionErrorStore` with all error state
(`lastNodeErrors`, `lastExecutionError`, `lastPromptError`), computed
properties (`hasAnyError`, `totalErrorCount`,
`activeGraphErrorNodeIds`), and UI state (`isErrorOverlayOpen`,
`showErrorOverlay`, `dismissErrorOverlay`)
- **Moved util**: `executionIdToNodeLocatorId` extracted to
`graphTraversalUtil`, reusing `traverseSubgraphPath` and accepting
`rootGraph` as parameter
- **Updated consumers**: 12 files updated to import from
`executionErrorStore`
- **Backward compat**: Deprecated getters retained in `ComfyApp` for
extension compatibility

## Review Focus
- Deprecated getters in `app.ts` — can be removed in a future
breaking-change PR once extension authors migrate

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9060-refactor-Extract-executionErrorStore-from-executionStore-30e6d73d36508101973de835ab6b199f)
by [Unito](https://www.unito.io)
This commit is contained in:
jaeone94
2026-02-22 09:51:22 +09:00
committed by GitHub
parent d9fdb01d9b
commit 8aa4e36fd5
20 changed files with 425 additions and 373 deletions

View File

@@ -60,6 +60,7 @@ import { useApiKeyAuthStore } from '@/stores/apiKeyAuthStore'
import { useCommandStore } from '@/stores/commandStore'
import { useDomWidgetStore } from '@/stores/domWidgetStore'
import { useExecutionStore } from '@/stores/executionStore'
import { useExecutionErrorStore } from '@/stores/executionErrorStore'
import { useExtensionStore } from '@/stores/extensionStore'
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
@@ -218,18 +219,18 @@ export class ComfyApp {
/**
* The node errors from the previous execution.
* @deprecated Use useExecutionStore().lastNodeErrors instead
* @deprecated Use app.extensionManager.lastNodeErrors instead
*/
get lastNodeErrors(): Record<NodeId, NodeError> | null {
return useExecutionStore().lastNodeErrors
return useExecutionErrorStore().lastNodeErrors
}
/**
* The error from the previous execution.
* @deprecated Use useExecutionStore().lastExecutionError instead
* @deprecated Use app.extensionManager.lastExecutionError instead
*/
get lastExecutionError(): ExecutionErrorWsMessage | null {
return useExecutionStore().lastExecutionError
return useExecutionErrorStore().lastExecutionError
}
/**
@@ -713,7 +714,7 @@ export class ComfyApp {
})
}
} else if (useSettingStore().get('Comfy.RightSidePanel.ShowErrorsTab')) {
useExecutionStore().showErrorOverlay()
useExecutionErrorStore().showErrorOverlay()
} else {
useDialogService().showExecutionErrorDialog(detail)
}
@@ -1402,9 +1403,8 @@ export class ComfyApp {
this.processingQueue = true
const executionStore = useExecutionStore()
executionStore.lastNodeErrors = null
executionStore.lastExecutionError = null
executionStore.lastPromptError = null
const executionErrorStore = useExecutionErrorStore()
executionErrorStore.clearAllErrors()
// Get auth token for backend nodes - uses workspace token if enabled, otherwise Firebase token
const comfyOrgAuthToken = await useFirebaseAuthStore().getAuthToken()
@@ -1440,8 +1440,8 @@ export class ComfyApp {
})
delete api.authToken
delete api.apiKey
executionStore.lastNodeErrors = res.node_errors ?? null
if (executionStore.lastNodeErrors?.length) {
executionErrorStore.lastNodeErrors = res.node_errors ?? null
if (executionErrorStore.lastNodeErrors?.length) {
this.canvas.draw(true, true)
} else {
try {
@@ -1477,7 +1477,8 @@ export class ComfyApp {
console.error(error)
if (error instanceof PromptExecutionError) {
executionStore.lastNodeErrors = error.response.node_errors ?? null
executionErrorStore.lastNodeErrors =
error.response.node_errors ?? null
// Store prompt-level error separately only when no node-specific errors exist,
// because node errors already carry the full context. Prompt-level errors
@@ -1489,13 +1490,13 @@ export class ComfyApp {
if (!hasNodeErrors) {
const respError = error.response.error
if (respError && typeof respError === 'object') {
executionStore.lastPromptError = {
executionErrorStore.lastPromptError = {
type: respError.type,
message: respError.message,
details: respError.details ?? ''
}
} else if (typeof respError === 'string') {
executionStore.lastPromptError = {
executionErrorStore.lastPromptError = {
type: 'error',
message: respError,
details: ''
@@ -1504,7 +1505,7 @@ export class ComfyApp {
}
if (useSettingStore().get('Comfy.RightSidePanel.ShowErrorsTab')) {
executionStore.showErrorOverlay()
executionErrorStore.showErrorOverlay()
}
this.canvas.draw(true, true)
}
@@ -1533,7 +1534,7 @@ export class ComfyApp {
} finally {
this.processingQueue = false
}
return !executionStore.lastNodeErrors
return !executionErrorStore.lastNodeErrors
}
showErrorOnFileLoad(file: File) {
@@ -1880,10 +1881,8 @@ export class ComfyApp {
clean() {
const nodeOutputStore = useNodeOutputStore()
nodeOutputStore.resetAllOutputsAndPreviews()
const executionStore = useExecutionStore()
executionStore.lastNodeErrors = null
executionStore.lastExecutionError = null
executionStore.lastPromptError = null
const executionErrorStore = useExecutionErrorStore()
executionErrorStore.clearAllErrors()
useDomWidgetStore().clear()