Pre-existing finding surfaced by the silent-failure-hunter reviewer on PR #23.
Two production code paths catch every Exception and emit a single warn: line to stderr while continuing the loop:
src/xbrain/executors/api.py:107-114 (ApiExecutor.enrich_items)
src/xbrain/topic_synth.py:102-109 (synthesize_overviews_api)
A 100%-broken run currently looks like a no-op success. The CLI prints e.g. Topics sintetizados: 0/12 · 12 páginas escritas and exits 0 even when every single topic failed for the same reason.
Scope
- Narrow each catch to a concrete tuple:
(anthropic.APIError, ValueError, json.JSONDecodeError, xbrain.validate.ValidationError).
- Count failures alongside successes; surface the totals in the stdout summary (e.g.
Topics sintetizados: 0/12 · 12 fallidos).
- Raise a non-zero exit when
failures == len(items) and no successes — a completely-failed batch is not a successful run.
- Keep partial-success behaviour: 11 successes + 1 failure should still write the 11 and exit 0 with a warning.
Tests
- Existing tests assert successful batches still succeed.
- New tests: monkeypatch the client to raise on all items; assert non-zero exit and a clear summary line.
- New tests: monkeypatch to raise on a subset; assert partial-success behaviour.
Out of scope
- Structured logging migration (the
print(..., file=sys.stderr) pattern is consistent with the rest of the project; that is a separate refactor).
- The
_handle_cli_errors swallow in cli.py (similar shape, separate issue if needed).
Pre-existing finding surfaced by the silent-failure-hunter reviewer on PR #23.
Two production code paths catch every
Exceptionand emit a singlewarn:line to stderr while continuing the loop:src/xbrain/executors/api.py:107-114(ApiExecutor.enrich_items)src/xbrain/topic_synth.py:102-109(synthesize_overviews_api)A 100%-broken run currently looks like a no-op success. The CLI prints e.g.
Topics sintetizados: 0/12 · 12 páginas escritasand exits 0 even when every single topic failed for the same reason.Scope
(anthropic.APIError, ValueError, json.JSONDecodeError, xbrain.validate.ValidationError).Topics sintetizados: 0/12 · 12 fallidos).failures == len(items)and no successes — a completely-failed batch is not a successful run.Tests
Out of scope
print(..., file=sys.stderr)pattern is consistent with the rest of the project; that is a separate refactor)._handle_cli_errorsswallow incli.py(similar shape, separate issue if needed).