Skip to content

fix: multi-file password state loss, silent empty success, and zombie Java process on timeout#65

Merged
davidamunga merged 3 commits into
mainfrom
fix/bugs-1-4-5
Jul 14, 2026
Merged

fix: multi-file password state loss, silent empty success, and zombie Java process on timeout#65
davidamunga merged 3 commits into
mainfrom
fix/bugs-1-4-5

Conversation

@davidamunga

@davidamunga davidamunga commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

Three bug fixes, each with its own patch changeset.

Bug 1 — Multi-file password state loss

When processing a batch and a mid-batch file triggers the password prompt, processFiles returned early without calling setStatements. handlePasswordSubmit then built updatedStatements from the React state (always [] at that point), silently dropping every file processed before the protected one.

Fix: a pendingStatements ref captures the already-processed statements whenever a password is needed. handlePasswordSubmit seeds its list from the ref (and updates it again if another file in the same batch also needs a password).

Bug 4 — Silent empty success

If parseTabulaCSV found no recognisable header (wrong PDF, scan artefacts, etc.) it returned { transactions: [] }. processFiles pushed that onto the batch and ultimately showed a SUCCESS screen with "0 transactions" — no indication anything was wrong.

Fix: after parseTabulaCSV, throw if transactions.length === 0. The existing catch block routes this to the ERROR state with a clear message.

Bug 5 — Timeout leaves Java running

Promise.race with a 60 s timeout rejected the UI-side promise but left the Rust extract_pdf_tables command (and its Java/Tabula subprocess) running indefinitely.

Fix (Rust): switched from cmd.output() to cmd.spawn() + child.wait_with_output(), storing the child PID in Tauri-managed ActivePid state. A new cancel_pdf_extraction command reads and clears the PID then kills the process (kill -9 / taskkill /F).

Fix (TS): the timeout handler now calls invoke("cancel_pdf_extraction") before rejecting, and .finally(() => clearTimeout(...)) on the extraction promise prevents the timer firing after a normal completion.

Test plan

  • Upload 3 PDFs where the second is password-protected — verify the first and third are included in the final export
  • Upload a non-M-PESA PDF — verify the UI shows an error ("No transactions found") instead of a success screen with 0 transactions
  • Upload a very large or deliberately slow PDF and let it time out — verify the Java process is no longer visible in Activity Monitor / Task Manager after the timeout

Pass filteredStatement to all optional Excel analytics sheets so filters
like "exclude charges" and sort order are consistently applied. The
Charges & Fees sheet intentionally retains the unfiltered statement since
its sole purpose is to display charge transactions.
…aves Java running

Bug 1 – preserve already-processed statements in a ref when a mid-batch
file triggers a password prompt so handlePasswordSubmit doesn't rebuild
the list from stale (empty) React state.

Bug 4 – throw an error after parseTabulaCSV when zero transactions are
found so the UI reaches ERROR rather than a silent SUCCESS screen.

Bug 5 – switch Tabula spawn from output() to spawn()+wait_with_output(),
store the child PID in Tauri managed state, and add a cancel_pdf_extraction
command. The TS timeout now calls that command before rejecting so the
Java process is killed rather than left running in the background.
Repository owner deleted a comment from cursor Bot Jul 14, 2026
@davidamunga
davidamunga merged commit 93ede91 into main Jul 14, 2026
8 of 12 checks passed
@davidamunga
davidamunga deleted the fix/bugs-1-4-5 branch July 14, 2026 19:14
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