Fava client hardening: write-lock coverage, shared HTTP client, JSON assertions #58
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/fava-client-hardening"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fourth PR of the refactor series (stacked on #57 → #56 → #55; merge in order).
Problems (CODE-REVIEW-2026-06 #7, #14, #15, #19 + libra-#23, libra-#39, libra-#53):
/sourcewith no lock at all — two concurrent mutations raced each other and every other ledger writer (libra-#23).ChecksumConflictErrorexisted but was never raised; 409/412 leaked as rawHTTPStatusError500s.httpx.AsyncClientinstantiations — a TCP handshake per Fava request.POST /assertionssubmitted a Beancount source string to Fava's JSON API — every assertion create 500'd (libra-#39).get_all_accountsround-trip (libra-#53).Changes:
FavaClient.transform_source_line(filename, lineno, fn)— the whole read-modify-write under_write_lock, 409/412 →ChecksumConflictError. Approve/reject rewired through it; conflicts surface as HTTP 409.update_entry_source/delete_entryraiseChecksumConflictErroron 409/412.httpx.AsyncClientper FavaClient withaclose()wired intolibra_stop; health probes keep a 2s per-request timeout._validate_bql_accountguards both interpolation sites (^[A-Za-z0-9:_-]+$).format_balancereturns Fava's{"t": "Balance", "amount": {number, currency}}dict — the seven strict-xfail reconciliation tests flip to passing.sync_single_account_from_beancountgrowsassume_existsso the add-account endpoint skips the redundant verification round-trip.Not addressed: libra-#43 (newer-Fava "non-source file" 500) — could not reproduce against fava 1.30.13 in the test harness (all add-account tests pass); it may predate the
_resolve_target_filefix ind82443d. Worth re-testing on the deployed Fava version before closing.Tests: new concurrent approve+reject test (both mutations must land); 7 reconciliation xfails now real passes. Full suite: 176 passed, 3 skipped, 0 xfailed.
🤖 Generated with Claude Code
format_balance returned a Beancount source string, but fava.add_entry feeds PUT /add_entries whose deserialiser expects {"t": "Balance", "amount": {"number", "currency"}, ...} — every assertion create 500'd. Returns the dict shape now. The seven strict-xfail reconciliation tests tracking this flip to regular passing tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.