Report a malformed trace line as the exit-2 document, not a traceback - #37
Merged
Conversation
A trace file with one line that is not a TraceEvent — a process killed mid-write, a hand edit — made `grapharc trace`, `grapharc metrics` and `grapharc viz` crash with a raw pydantic ValidationError: exit 1, nothing on stdout even in --json mode. The CLI's own contract in grapharc/cli/output.py names "an unreadable trace" as EXIT_UNAVAILABLE = 2, and exit 1 is reserved for "the command ran and the answer was negative" — so a script watching a run concluded the run differed rather than that the file was unreadable, while `replay` and `diff` answered the same broken file politely. `read_events` now raises TraceReadError(path, line_number, cause) naming the file and the 1-based line — "unreadable trace file: /tmp/bad.jsonl: line 1 is not a trace event" — instead of letting the pydantic field listing escape. It still raises rather than skips: a partially-read audit trail presented as complete would be worse than a refusal. The three reading commands catch it and route through fail(...) with the default EXIT_UNAVAILABLE, the same shape _existing_trace and viz's ReplayError handler already use: text mode puts `error: …` on stderr with empty stdout, JSON mode makes the failure the one document on stdout with empty stderr. Well-formed traces read exactly as before. Fixes #15 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
grapharc trace,grapharc metricsandgrapharc vizcrashed with a raw pydanticValidationErrortraceback (exit 1, empty stdout even in--jsonmode) when the trace file contained a line that is not a validTraceEvent— a truncated final line from a process killed mid-write, a hand edit, any stray line. The CLI's own contract ingrapharc/cli/output.pynames "an unreadable trace" asEXIT_UNAVAILABLE = 2, and exit 1 is reserved for "the command ran and the answer was negative" — so scripts drew the wrong conclusion, andreplay/diffanswered the same broken file politely while their three siblings crashed.How
grapharc/observe/trace.py:read_eventsnow raisesTraceReadError(path, line_number, cause)when a line does not parse, with a message naming the file and the 1-based line —unreadable trace file: /tmp/bad.jsonl: line 1 is not a trace event. It keeps raising rather than skipping: a partially-read audit trail presented as complete would be worse than a refusal. Exported fromgrapharc.observealongsideTraceRecorder.grapharc/cli/main.py:_cmd_trace,_cmd_metricsand_cmd_vizcatch it and route throughfail(...)with the defaultEXIT_UNAVAILABLE, following the_existing_trace/ReplayError-handler shape already in the file. Text mode:error: …on stderr, empty stdout. JSON mode: the failure is the one document on stdout, stderr empty.tests/test_cli.py: two parametrized tests over all three commands — text mode asserts exit 2 with the exacterror:line naming the file and line number, JSON mode asserts exit 2 with exactly one{"ok": false, ...}document and empty stderr. Verified red with the source fix reverted (all six raiseValidationErroron today's tree).Out of scope, per the issue:
replay/diff, skipping bad lines, the server's trace endpoints, andthread_summary's incremental index are untouched. Well-formed traces read byte-identically to before, so no README/cookbook transcript changes.Verification
pytest: 1647 passed, 12 deselected (including the byte-compared README/cookbook transcripts)ruff check .: cleanFixes #15
🤖 Generated with Claude Code