Skip to content

claude-code-chat-browser: Return non-zero CLI exit code on partial export failure #51

@clean6378-max-it

Description

@clean6378-max-it

Problem

The CLI export script at scripts/export.py:544-548 catches parse failures per-session with except Exception as e: print(..., file=sys.stderr); continue and always exits with code 0, regardless of how many sessions failed. There is no machine-readable distinction between "exported 50 of 50" and "exported 48 of 50, 2 failed."

For scripted use (CI pipelines, cron jobs, monitoring), callers cannot detect data loss in exported archives.

Goal

Add exit-code semantics and a stderr summary to cmd_export() wrapper only — not the shared export engine. The engine (PR1) exposes failure_count; the CLI maps it to process exit codes.

Prerequisites

Merge PR1 first (feat/export-engine — shared export engine with failure_count in result).

git checkout master
git pull
git checkout -b feat/cli-export-exit-codes

Scope

Exit code mapping (in scripts/export.py cmd_export())

Condition Exit code
All attempted sessions exported successfully 0
Some exported, some failed (partial failure) 2
Zero exported, one or more failures (total failure) 1

Stderr summary

Print at end of bulk export:

Exported N of M sessions (K failed)

Use result.exported_count, result.total_candidates, and result.failure_count from the shared engine.

Preserve existing behavior where appropriate

  • Per-session failure: continue exporting remaining sessions (do not remove the catch-and-continue pattern).
  • Empty export with no failures (all skipped / nothing new): preserve current "Nothing to export." messaging and exit 0 unless product explicitly wants otherwise — document in PR.
  • HTTP API unchanged (still uses JSON error responses, not process exit codes).
  • sys.exit() logic lives in CLI wrapper, not utils/export_engine.py.

Documentation

Document exit codes in build_parser() epilog and/or README CLI Export section:

Exit codes (export subcommand):
  0 — all sessions exported successfully
  1 — total failure (no sessions exported; one or more errors)
  2 — partial failure (some sessions exported, some failed)

Tests (≥2)

Add to tests/test_cli_e2e.py or new tests/test_cli_export_exit_codes.py:

Test Setup Assert
Clean export Valid session_minimal.jsonl seeded via _seed_base_dir returncode == 0
Partial failure One valid + one corrupt session file returncode == 2; stderr contains failure summary

Optional third test: all corrupt → returncode == 1.

Use subprocess via existing _run_cli() helper; isolate export state to tmp_path.

Out of Scope

  • HTTP export error semantics
  • Changing shared engine to call sys.exit
  • JSONL parser split (Thursday)
  • Structured logging replacement for print() warnings (separate backlog item if any)

Acceptance Criteria

  • CLI exits 0 when all sessions export successfully
  • CLI exits 2 when some sessions fail but others succeed (partial failure)
  • CLI exits 1 when export fails entirely (no sessions exported, ≥1 failure)
  • Stderr summary: Exported N of M sessions (K failed)
  • Exit codes documented in --help epilog or README
  • ≥2 tests: clean export (exit 0) and partial failure (exit 2)
  • Existing export tests still pass
  • pytest -q green in CI
  • PR approved by at least 1 reviewer

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions