Commit c5a7448
fix(automation): create_record surfaces the engine's DUPLICATE_RECORD code (#14948)
* fix(automation): create_record surfaces the engine's DUPLICATE_RECORD code
engine.insert (#14095) raises DuplicateRecordError with a classified
`code: 'DUPLICATE_RECORD'` (ADR-0112), driver-independent. The
create_record node executor threw it away, collapsing every failure
into one opaque string, so a flow's only two error-handling
primitives -- try_catch and a fault edge -- could not tell "already
there" from "the store is down".
- NodeExecutionResult gains an optional `code?: string`, beside the
existing `errorClass`, set (via a duck-typed StandardErrorCode
check, not an objectql-class import -- objectql is this package's
devDependency only) when create_record's catch sees the classified
code.
- AutomationEngine copies it onto the `$error` run variable beside
`message` when a node fails by returning.
- try_catch's executor preserves it across its own errorVariable
binding, which previously reconstructed `{ nodeId, message }` from
the caught exception's message alone and silently dropped it.
Deliberately scoped to create_record: update_record / delete_record
collapse the same way, but engine.update still leaks the raw driver
error (#14390, not yet fixed), so those node results have nothing
structured to surface yet.
Fixes #14419
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
* chore: regenerate system-context-census after merging origin/main
pre-push refused a stale merged artifact: the merge brought in an
auth-plugin.ts line shift the census's anchor didn't follow. Regenerated
via `pnpm gen:system-context-census` per AGENTS.md's merge-driver deferral
protocol (this is the discharging commit right after the merge, not the
merge itself).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
* fix(automation): patch round 1 — identity guard for stale $error.code, test corrections, spec-gap deferral
Tier contract review on PR #14948 returned PASS WITH REQUIRED PATCHES.
Three patches, all addressed:
P1 (the round's reason — a correctness defect the review reproduced):
try_catch reads `code` off the run-wide $error, but the engine only
rewrites $error when a failing node RETURNS a failure, or THROWS
through a node with its own `fault` edge. A node inside a try_catch's
try region never has a fault edge of its own (the region's synthetic
sub-flow carries only the region's own edges), so a node that fails by
THROWING (a timeoutMs firing, a dying nested container) used to leave
$error exactly as an earlier, unrelated failure left it -- including
its code. Fixed with a minimal identity guard in try-catch-node.ts:
capture $error at the start of each attempt, trust the post-catch
$error only if it actually changed. Two repro flows pinned (a loop
sweeping a duplicate row then a timing-out row; a plain flow where an
earlier fault-routed duplicate must not leak into a later unrelated
try_catch) -- verified red on the pre-guard code, green after.
P2: packages/spec's TryCatchErrorValueSchema doesn't declare `code`
yet and strips it on a strict parse. packages/spec is single-owner
(domain:spec); deferred and filed as #14954, named in the changeset.
content/docs/automation/flows.mdx (hand-written) now mentions
{$error.code}; content/docs/references/automation/control-flow.mdx
(generated from spec) is untouched.
P3: the "sets code: DUPLICATE_RECORD" regression pin never actually
asserted `code`, and its comment about the step log carrying it was
wrong. Both regression-pin tests now register a fault-edge handler
that reads $error directly and assert `code` on it.
Fold-in: NodeExecutionResult.code's JSDoc now states create_record
narrows deliberately to DUPLICATE_RECORD; changeset notes a custom
IDataEngine throwing { code: 'DUPLICATE_RECORD' } directly is
correctly duck-typed as a duplicate too (ADR-0112).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 9c7237c commit c5a7448
7 files changed
Lines changed: 547 additions & 10 deletions
File tree
- .changeset
- content/docs
- automation
- permissions
- packages/services/service-automation/src
- builtin
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1080 | 1080 | | |
1081 | 1081 | | |
1082 | 1082 | | |
1083 | | - | |
| 1083 | + | |
1084 | 1084 | | |
1085 | 1085 | | |
1086 | 1086 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
168 | 168 | | |
169 | 169 | | |
170 | 170 | | |
171 | | - | |
| 171 | + | |
172 | 172 | | |
173 | 173 | | |
174 | 174 | | |
| |||
0 commit comments