Skip to content

feat: graceful CLI error handling for YAML and Python-block errors - #10

Merged
connorferster merged 2 commits into
mainfrom
features/cli-error-handling
Aug 14, 2026
Merged

feat: graceful CLI error handling for YAML and Python-block errors#10
connorferster merged 2 commits into
mainfrom
features/cli-error-handling

Conversation

@connorferster

Copy link
Copy Markdown
Contributor

Summary

Author mistakes no longer crash the CLI with a raw Python traceback. YAML syntax errors and exceptions raised inside _py blocks are caught and presented as friendly, compact, actionable reports that make clear the problem is in the authored document, not an ymprint bug. Genuine internal errors still propagate as normal tracebacks.

What's included

Error model — new YmprintAuthoringError hierarchy (errors.py):

  • YamlSyntaxError — wraps ruamel errors with file/line/column
  • PythonBlockError — wraps _py block exceptions, keeping the author's source + traceback

Raised at the two failure points: yaml_loader.load_yaml() (parse) and blocks/python_block.py (exec).

convert — catches authoring errors, prints a red panel titled "error in your document" and exits 1.

live — redesigned as a two-region rich.Panel:

  • Upper: 👁 YMPrint live header, the watched-file list, and the throbber
  • Lower: ✓ Reloaded … at <timestamp> / ⟳ reloading… / the compact error
  • Border colour tracks state (cyan/yellow/green/red); throbber fires a red explosion on a failed reload
  • A reload failure shows the error in-place instead of killing the session, cleared on the next save

Compact tracebacks (error_display.py) — keep the top 2 + bottom 3 frames with a … N hidden … marker; map the <string> exec frame back to the author's block source and highlight the failing line.

SyntaxError handling — a compile-time error has no <string> frame, so it uses the exception's own .lineno/.text, and detects the common source: vs source: | folding mistake with an actionable block-scalar hint.

Fixes — two latent live bugs (undefined CONFIG_FILENAMES; locate_config_file returning a bare filename from the wrong ancestor) and a stray debug print that corrupted the live display.

Tests

New tests/test_cli_errors.py: YAML errors, convert exit code, Python-block runtime errors, top/bottom truncation, and both SyntaxError variants (folded vs genuine multi-line). Full suite: 66 passing.

🤖 Generated with Claude Code

connor-sp and others added 2 commits August 14, 2026 03:05
Author mistakes no longer crash the CLI with a raw traceback. YAML syntax
errors and exceptions raised inside `_py` blocks are now caught and presented
as friendly, actionable reports that make clear the problem is in the authored
document, not an ymprint bug.

- Add YmprintAuthoringError hierarchy (YamlSyntaxError, PythonBlockError)
- Raise these at the parse (yaml_loader) and exec (python_block) sites
- error_display: compact top-and-bottom traceback truncation; maps `<string>`
  exec frames back to the author's block source and highlights the failing line
- convert: wrap render, show a red error panel and exit 1 on authoring errors
- live: redesigned two-part rich Panel (watch list + throbber over a status
  area) with a state-coloured border; reload failures show the error in-place
  instead of killing the session, cleared on the next save
- throbber: red error-explosion burst on failed reload
- Fix latent live bugs: undefined CONFIG_FILENAMES and locate_config_file now
  returns the nearest config as a full path
- Remove a stray debug print that corrupted the live display
- Tests for YAML/Python-block errors, convert exit code, and truncation

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A SyntaxError fails at compile time, so exec() produces no `<string>` traceback
frame — the previous formatter could only show the internal exec frame with no
author context. Handle SyntaxError specially:

- Use the exception's own .lineno/.text to show the offending code line
- Detect the common cause of a `_py` block collapsing to a single line (writing
  `source:` instead of `source: |`, which folds the code) and emit an actionable
  hint to use a YAML block scalar
- Clean up the final message (drop the redundant "(<string>, line N)")

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@connorferster
connorferster merged commit e414d49 into main Aug 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants