Commit 1885834
committed
backup: #904 v10 - classify adapter-data rejections as exit 2
## Codex P2 v9: adapter encoder rejections fall through to exit 1
When an adapter encoder rejects the input tree's contents (a malformed
DynamoDB _schema.json, an S3 collision artifact the encoder cannot
reverse, an SQS side-record with an unknown kind, etc.), the error
propagates out of EncodeSnapshot but does not match any of the three
exit-2 sentinels (ErrSelfTestLowerLastCommitTS,
ErrEncodeUnsupportedDynamoDBLayout, errSelfTestMismatch), so the
CLI's run() falls through to exit 1. Per the CLI contract, exit 1
is operator/flag error and exit 2 is data-correctness — runbooks
branch on exit status to quarantine bad dump data, so misclassifying
adapter rejections as user error is a real ergonomic regression.
The encoder is offline-only — it operates entirely on local files
under InputRoot. Every error from an adapter encoder originates from
the contents of that tree (a sentinel rejection, an unmarshalling
failure, etc.). Treating all adapter errors as data-correctness
matches the CLI contract.
Fix:
- New ErrEncodeAdapterData sentinel in internal/backup.
- runAdapterEncoders wraps each adapter error with errors.Mark so
errors.Is(err, ErrEncodeAdapterData) is true. Mark preserves the
inner sentinel chain — callers that errors.Is on the per-adapter
sentinel (ErrDDBEncodeInvalidSchema, ErrS3EncodeKeyConflict, etc.)
are unaffected.
- CLI run() gains a fourth exit-2 branch for ErrEncodeAdapterData.
Pinned by:
- TestEncodeSnapshotMarksAdapterDataErrors (library): malformed
_schema.json triggers ErrDDBEncodeInvalidSchema inside the DDB
encoder; assertion verifies BOTH errors.Is(ErrEncodeAdapterData)
AND errors.Is(ErrDDBEncodeInvalidSchema) hold - the mark is
additive, not lossy.
- TestCLIAdapterDataErrorExitsTwo (CLI): same fixture driven
end-to-end through run(); asserts exit code = 2 and no .fsm
published.
## Caller audit per CLAUDE.md semantic-change rule
- runAdapterEncoders return semantics: every non-nil err is now
marked. Sole caller is EncodeSnapshot; it propagates the marked
error unchanged.
- EncodeSnapshot callers (library tests, CLI's encodeToTempFile):
- Library tests that errors.Is on the validation sentinels
fire BEFORE runAdapterEncoders, so they are NOT marked.
- CLI's encodeToTempFile wraps with "EncodeSnapshot"; the run()
layer above it now matches ErrEncodeAdapterData and routes to
exit-2 (new branch).
- In-tree errors.Is on per-adapter sentinels (encode_dynamodb_test.go
et al.) call the adapter encoders directly, not through
EncodeSnapshot, so the mark wrapper is never on their path.
Tests + lint green. wrapcheck required errors.WithStack around the
Mark.1 parent 145a912 commit 1885834
4 files changed
Lines changed: 106 additions & 3 deletions
File tree
- cmd/elastickv-snapshot-encode
- internal/backup
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
85 | | - | |
86 | | - | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
87 | 90 | | |
88 | 91 | | |
89 | 92 | | |
90 | 93 | | |
91 | 94 | | |
92 | 95 | | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
93 | 99 | | |
94 | 100 | | |
95 | 101 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
80 | 120 | | |
81 | 121 | | |
82 | 122 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
44 | 60 | | |
45 | 61 | | |
46 | 62 | | |
| |||
353 | 369 | | |
354 | 370 | | |
355 | 371 | | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
356 | 378 | | |
357 | 379 | | |
358 | 380 | | |
359 | 381 | | |
360 | 382 | | |
361 | 383 | | |
362 | 384 | | |
363 | | - | |
| 385 | + | |
364 | 386 | | |
365 | 387 | | |
366 | 388 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
388 | 388 | | |
389 | 389 | | |
390 | 390 | | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
391 | 426 | | |
392 | 427 | | |
393 | 428 | | |
| |||
0 commit comments