Skip to content

feat: error contract completion — DocumentClosedError, error fields, find_text parity (ISSUES.md #42) - #59

Merged
pablospe merged 1 commit into
mainfrom
task/522dcbb1-Error-contract-completion--Doc
Jul 17, 2026
Merged

pablospe merged 1 commit into
mainfrom
task/522dcbb1-Error-contract-completion--Doc

Conversation

@pablospe

@pablospe pablospe commented Jul 17, 2026 •

Copy link
Copy Markdown
Owner

Summary

Completes the error contract for the LLM-facing API (ISSUES.md #42, dogfooding round 2, target 0.6.1):

  • New DocumentClosedError(DocxEditError) with a path field, raised by the _ensure_open() choke point instead of a bare ValueError. The message says how to recover (reopen with Document.open). Breaking for callers catching ValueError around post-close calls (pre-1.0, per task spec).
  • Structured keyword-only fields, messages unchanged: DocumentNotFoundError.path, WorkspaceSyncError.workspace_path/.source_path, CommentError.comment_id, RevisionError.revision_id/.group_id. Populated at every raise site that has the value in scope; left None where no meaningful value exists. revision_id has no populating site today (accept_revision/reject_revision return bool) — it exists for a stable contract.
  • find_text(text, occurrence=0, paragraph=None): paragraph-scoping parity with find_all. occurrence counts within the paragraph when scoped, document-wide otherwise; negative occurrence returns None instead of wrapping around; empty text raises ValueError (same guard both branches).
  • Docs: SKILL.md error-table rows + scoped-search prose; docs/api.md find_text signature, close() post-close note, exception entries with field docs.

Test plan

  • TestDocumentClosedError: 7 operation kinds post-close raise the typed error with path set and recovery hint in the message.
  • TestLifecycleErrorFields: field assertions for all four extended classes, including None-when-not-applicable cases.
  • TestFindTextScoped: scoped hit with coordinate-system proof, scoped miss, out-of-range/negative occurrence → None, stale hash, malformed ref, out-of-range index, empty text scoped+unscoped.
  • 19 existing post-close pytest.raises(ValueError) assertions migrated to DocumentClosedError.
  • Full suite: 1135 passed, 2 skipped. ruff check + ruff format --check clean; ty check diagnostics identical to baseline (7 pre-existing).

Summary by CodeRabbit

  • New Features

    • Added paragraph-scoped text searching with occurrence counting limited to the selected paragraph.
    • Added DocumentClosedError, now available from the top-level package.
    • Enhanced errors with structured context such as document paths, revision IDs, comment IDs, and workspace paths.
  • Bug Fixes

    • Operations after closing a document now consistently report a dedicated error.
    • Improved diagnostics for missing documents, stale workspaces, invalid revisions, and comment replies.
  • Documentation

    • Updated API and usage guidance for scoped searches, occurrence handling, and structured error recovery.

…find_text parity (ISSUES.md #42)

- New DocumentClosedError(DocxEditError) with path field, raised by the
  _ensure_open() choke point instead of a bare ValueError; message says
  how to recover (reopen with Document.open). Breaking for callers
  catching ValueError around post-close calls (pre-1.0, per task spec).
- Structured keyword-only fields, messages unchanged:
  DocumentNotFoundError.path, WorkspaceSyncError.workspace_path/
  .source_path, CommentError.comment_id, RevisionError.revision_id/
  .group_id. Populated at every raise site that has the value in scope.
- find_text(text, occurrence=0, paragraph=None): paragraph scoping
  parity with find_all (occurrence counts within the paragraph when
  scoped), shared non-empty-text guard, negative occurrence returns
  None instead of wrapping around.
- Docs: SKILL.md error table rows + scoped-search prose; docs/api.md
  find_text signature, close() note, exception entries.
@coderabbitai

coderabbitai Bot commented Jul 17, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9dde1d8a-510a-4811-baa0-0f28298dc3a9

📥 Commits

Reviewing files that changed from the base of the PR and between bc24838 and 4ce9d64.

📒 Files selected for processing (12)
  • docs/api.md
  • docx_editor/__init__.py
  • docx_editor/comments.py
  • docx_editor/document.py
  • docx_editor/exceptions.py
  • docx_editor/ooxml/unpack.py
  • docx_editor/track_changes.py
  • docx_editor/workspace.py
  • skills/docx/SKILL.md
  • tests/test_document.py
  • tests/test_error_quality.py
  • tests/test_find_all.py

📝 Walkthrough

Walkthrough

find_text now supports paragraph-scoped occurrence lookup. Error classes carry structured context, closed documents raise DocumentClosedError, and related exports, integrations, tests, and documentation are updated.

Changes

Search and structured error contracts

Layer / File(s) Summary
Paragraph-scoped text search
docx_editor/document.py, docx_editor/track_changes.py, tests/test_find_all.py, docs/api.md, skills/docx/SKILL.md
find_text accepts an optional paragraph reference, applies scoped occurrence rules, returns None for invalid occurrence positions, and validates empty, malformed, out-of-range, and stale references.
Structured errors and lifecycle handling
docx_editor/exceptions.py, docx_editor/workspace.py, docx_editor/ooxml/unpack.py, docx_editor/comments.py, docx_editor/__init__.py, tests/test_document.py, tests/test_error_quality.py, docs/api.md, skills/docx/SKILL.md
Exceptions store typed path, workspace, source, revision, group, and comment context; closed-document operations raise DocumentClosedError; exports, call sites, tests, and error documentation reflect the updated contracts.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Document
  participant RevisionManager
  participant ParagraphSearch
  Document->>RevisionManager: find_text(text, occurrence, paragraph)
  RevisionManager->>ParagraphSearch: find_all(text, paragraph)
  ParagraphSearch-->>RevisionManager: scoped matches
  RevisionManager-->>Document: SearchResult or None
Loading

Possibly related PRs

Poem

A bunny found a match in a paragraph bright,
Counted each occurrence just right.
Errors grew pockets for paths and IDs,
Closed docs now say, “Open me, please!”
Structured clues hop through the night.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.72% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: error contract completion, DocumentClosedError, structured error fields, and find_text parity.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task/522dcbb1-Error-contract-completion--Doc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.7%. Comparing base (bc24838) to head (4ce9d64).

Additional details and impacted files
@@          Coverage Diff          @@
##            main     #59   +/-   ##
=====================================
  Coverage   95.7%   95.7%           
=====================================
  Files         11      11           
  Lines       3721    3740   +19     
  Branches     742     744    +2     
=====================================
+ Hits        3562    3581   +19     
  Misses        73      73           
  Partials      86      86           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@pablospe
pablospe merged commit 8235f24 into main Jul 17, 2026
10 checks passed
pablospe added a commit that referenced this pull request Jul 23, 2026
…rity-format accept/reject, session perf (ISSUES.md #59) (#70)

* docs: round-4 dogfood notes — PEP-668 venv, group-reopen caveat, majority-format accept/reject, session perf (ISSUES.md #59)

Fold four documentation-only findings from round-4 dogfood testing into the
SKILL and mirror docs, each re-verified by execution:

- Installation: PEP-668 externally-managed refusal → venv recipe (ensurepip /
  python3-venv remedy, uv + pipx alternatives) in SKILL.md and docs/index.md.
- Revision groups: caveat that same-paragraph batch_edit/batch_rewrite ops
  share one changeset date and reconstruct as a single inferred group after
  reopen; use separate calls to keep them independently resolvable.
- Replace formatting: accept leaves the replacement uniformly in the majority
  rPr while each deletion run keeps its own, so a reject restores the mix
  (SKILL.md + docs/api.md).
- Session mode: never one exec per edit (~250ms/round-trip; loop in-kernel or
  batch_edit); project fields kernel-side for large find_all reads.

* docs: address multi-review nits — reconcile session-perf figures, api.md accept/reject parity, PEP-668 link

- Session perf: the batched "one exec" path can't be quoted below the ~250ms
  round-trip floor; state ~0.3s (one round-trip + in-kernel loop), ~40x less
  overhead, instead of ~0.2s/~60x.
- docs/api.md majority-format clause: mirror SKILL.md's clearer two-sentence
  phrasing ("its own original formatting"; bold Accepting/reject).
- SKILL.md PEP-668 note: hyperlink PEP-668 to match the docs/index.md copy.
@pablospe
pablospe deleted the task/522dcbb1-Error-contract-completion--Doc branch August 30, 2026 19:28
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