Commit 3f27f57
authored
refactor: encapsulate execution error store writes behind record actions (#13636)
## Summary
Encapsulate `executionErrorStore`'s raw error state behind record
actions and deduplicate the slot-matching/prompt-error-shape logic that
callers had copy-pasted around it.
## Changes
- **What**:
- `executionErrorStore`: new `recordNodeErrors` / `recordExecutionError`
/ `recordPromptError` actions; `lastNodeErrors` / `lastExecutionError` /
`lastPromptError` are now exposed as read-only computeds, so external
writes are a compile-time error. The empty-record → `null` normalization
lives in exactly one place, which also lets `hasNodeError` and
`clearExecutionStartErrors` drop their now-dead emptiness checks
(invariant: the record is always `null` or non-empty).
- Direct-assignment call sites migrated: `app.ts` (queuePrompt success +
`PromptExecutionError` paths), `executionStore.ts`
(execution/service-level/cloud-validation errors), `subgraphStore.ts`
(blueprint validation — key shape and empty-`errors` semantics
intentionally unchanged).
- `executionErrorUtil.ts`: extracted `normalizePromptError` (shared by
the HTTP catch path and `classifyCloudValidationError`, which previously
duplicated the object/string branching) and added `errorsForSlot` /
`hasErrorForSlot`, replacing six inline copies of the
`extra_info.input_name` matching across the store,
`useNodeErrorFlagSync`, and `useProcessedWidgets`.
- `app.queuePrompt()`'s public boolean result is preserved
byte-for-byte: a local `queueResultOverride` keeps the pre-normalization
semantics for the `PromptExecutionError` path (absent/`null`
`node_errors` → `true`, `{}`/populated → `false`, last processed queue
item wins across multi-item runs). Regression tests pin all three
branches, including a multi-item concurrency case.
- Tests: 12 suites that seeded error state by direct assignment now seed
through the record actions. `TabErrors.test.ts` moved off
`createTestingPinia({ initialState })` — `initialState` cannot seed
computed-exposed state and was silently no-oping — to `stubActions:
false` with action-based seeding, which also surfaced and fixed
schema-incomplete fixtures (`executed`, missing error `type`/`details`)
and a missing `refreshMissingModels` on the app mock.
- **Breaking**: none. `app.lastNodeErrors` (deprecated getter) and
`workspaceStore.lastNodeErrors` are read-only surfaces and keep working;
after a validation failure with an empty record they now read `null`
instead of `{}`, matching the advertised `Record | null` type and the
behavior the success path already had.
## Review Focus
- Behavior equivalence of the `queuePrompt` return contract:
`queueResultOverride` is set only in the `PromptExecutionError` catch
(`!nodeErrors`, computed before normalization) and reset on each
successful iteration; every other exit falls through to the
store-derived value as before. The `node_errors` field is typed optional
but arrives from an unvalidated `JSON.parse` on the error path, so
`null` is runtime-reachable — hence `!nodeErrors` rather than an
`undefined` check, with a `null`-seeding regression test.
- The store's null-or-non-empty invariant: `recordNodeErrors` and the
internal clear path are the only writers; both normalize.1 parent 1c396f6 commit 3f27f57
20 files changed
Lines changed: 608 additions & 454 deletions
File tree
- src
- components
- error
- rightSidePanel/errors
- composables/graph
- renderer/extensions
- linearMode
- vueNodes/composables
- scripts
- stores
- utils
- __tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
152 | 152 | | |
153 | 153 | | |
154 | 154 | | |
155 | | - | |
| 155 | + | |
156 | 156 | | |
157 | | - | |
| 157 | + | |
158 | 158 | | |
159 | 159 | | |
160 | 160 | | |
| |||
189 | 189 | | |
190 | 190 | | |
191 | 191 | | |
192 | | - | |
| 192 | + | |
193 | 193 | | |
194 | | - | |
| 194 | + | |
195 | 195 | | |
196 | 196 | | |
197 | 197 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
131 | 131 | | |
132 | 132 | | |
133 | 133 | | |
134 | | - | |
| 134 | + | |
135 | 135 | | |
136 | | - | |
| 136 | + | |
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
| |||
168 | 168 | | |
169 | 169 | | |
170 | 170 | | |
171 | | - | |
| 171 | + | |
172 | 172 | | |
173 | | - | |
| 173 | + | |
174 | 174 | | |
175 | 175 | | |
176 | 176 | | |
| |||
207 | 207 | | |
208 | 208 | | |
209 | 209 | | |
210 | | - | |
| 210 | + | |
211 | 211 | | |
212 | | - | |
| 212 | + | |
213 | 213 | | |
214 | 214 | | |
215 | 215 | | |
| |||
248 | 248 | | |
249 | 249 | | |
250 | 250 | | |
251 | | - | |
| 251 | + | |
252 | 252 | | |
253 | 253 | | |
254 | 254 | | |
| |||
257 | 257 | | |
258 | 258 | | |
259 | 259 | | |
260 | | - | |
| 260 | + | |
261 | 261 | | |
262 | 262 | | |
263 | 263 | | |
| |||
474 | 474 | | |
475 | 475 | | |
476 | 476 | | |
477 | | - | |
| 477 | + | |
478 | 478 | | |
479 | | - | |
| 479 | + | |
480 | 480 | | |
481 | 481 | | |
482 | 482 | | |
| |||
Lines changed: 6 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
| 66 | + | |
70 | 67 | | |
71 | 68 | | |
72 | 69 | | |
| |||
83 | 80 | | |
84 | 81 | | |
85 | 82 | | |
86 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
87 | 88 | | |
88 | 89 | | |
89 | 90 | | |
| |||
0 commit comments