Skip to content

emrg: fix bare excepts in app.py and add write_tool tests - #10

Merged
argszero merged 1 commit into
masterfrom
fix/bare-excepts-and-write-tool-tests
Jul 18, 2026
Merged

argszero merged 1 commit into
masterfrom
fix/bare-excepts-and-write-tool-tests

Conversation

@argszero

Copy link
Copy Markdown
Owner

Changes

1. Fix bare except Exception: pass in app.py (3 places)

  • Line 498: except Exception: passexcept (ConnectionError, OSError): pass — wait_closed() in ping probe
  • Line 1481: except Exception: passexcept Exception: logger.debug(...) — terminal resize handler now logs errors instead of silently swallowing
  • Line 1499: except Exception: passexcept (ConnectionError, OSError): pass — wait_closed() in cleanup block

2. Add tests/test_write_tool.py (6 tests)

  • test_write_creates_file — basic file creation
  • test_write_overwrites_file — overwriting existing file
  • test_write_creates_parent_directories — auto-creates nested dirs
  • test_write_missing_file_path — error on missing file_path
  • test_write_empty_content — writing empty string
  • test_write_large_content_ok — 100KB file (well under 10MB limit)

Verification

  • ✅ 56 tests passing
  • ✅ import check: from emrg.client.app import run_client
  • ✅ CLI: python -m emrg --help

- Replace bare except Exception: pass in app.py with specific exceptions
  (ConnectionError, OSError) for wait_closed() calls, and add debug logging
  for terminal resize handler errors.
- Add tests/test_write_tool.py with 6 tests covering create, overwrite,
  parent directory creation, missing params, empty content, and large files.

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle #9

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle #10

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle #11

@argszero
argszero merged commit 6e204f1 into master Jul 18, 2026
@argszero
argszero deleted the fix/bare-excepts-and-write-tool-tests branch July 18, 2026 03:25
argszero added a commit that referenced this pull request Jul 21, 2026
)

Rant #10: PR #92 over-implemented — 8KB truncation in system prompt was
not requested, only write logging was needed for root-cause diagnosis.
Revert _MAX_MEMORY_INDEX_BYTES constant, _truncate_index method, and
truncation logic in _build_memory_section.  Keep memory.py logging
(_save_index/save entry count + size delta + source annotation).

Co-authored-by: EMRG Evolution <emrg@argszero.dev>
argszero added a commit that referenced this pull request Jul 23, 2026
…155)

When ESC is pressed alone (not part of an escape sequence), InputParser
receives 0x1B and sets need=2, waiting for subsequent bytes that never come.
The main event loop's 50ms has_pending timeout breaks without flushing the
buffered standalone ESC byte, making escape key unusable for interrupting
LLM responses.

Fix: In TimeoutError handler, check if parser buffer contains only b'\x1b'
and flush it as a standalone keypress. Inspired by Claude Code's
parse-keypress.ts:268 timer flush pattern.

Co-authored-by: EMRG Evolution <emrg@argszero.dev>
argszero added a commit that referenced this pull request Sep 18, 2026
…1388)

A red plan's rows are re-run on the base tree to decide who owns them (issue
#1378), so a row that is not the row that failed attributes the failure to the
wrong tree. The rows came from the text summary, which separates a node id from
its failure message with `" - "` - a substring node ids themselves contain:
measured on this repository's own suite, 22 of its 3227 node ids contain it, and
all 22 were cut (`…[git commit -q -F`). The cut row is one the base does not
contain, which reads as "the base fails nothing", and the plan's tree is told to
re-push a PR that owns nothing - the harm #1378 removed, still there for those
rows (issue #1386).

So the rows come from the run's own machine-readable report: `--junitxml` with
`-o junit_family=xunit1`, the family that writes `file`, without which a
classname cannot be turned back into a path. Every `<testcase>` carrying a
`<failure>` or `<error>` becomes a node id. Two shapes are pinned by tests
against real pytest runs - an id containing `" - "`, and one containing a
newline, which the text report breaks across lines and junit escapes as
`&#10;`. A report that cannot be parsed, or a record whose node id cannot be
built, is `could not measure` (exit 2), never a guessed row; a run that writes no
report falls back to the text parse and says so on stderr.

The same loss was in the base run's `not found:` report, the other text channel
this walk reads: the argument is a node id, and reading it up to the first
whitespace returned `set()` for a missing `…[git commit -q -F - <<EOF]` - i.e.
"could not measure" for a question the run had just answered. It is read to the
end of its line now, and the base's failing rows are a set intersection against
the rows that were asked for rather than a parse.

Measured on the real corpus (2026-09-18): the reader rebuilds all 100 node ids of
the two affected files identically to `pytest --collect-only`, and both shapes
round-trip through pytest as arguments.

Closes #1386

Co-authored-by: EMRG Evolution <emrg@argszero.dev>
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.

1 participant