core+gui: name the real cause of a failed build instead of guessing #7

Merged
bitcoinafterlife merged 1 commits from ui/build-will-error-messages into main 2026-09-09 12:31:28 +00:00

The Building Will report showed a fixed list of three "possible reasons"
whenever a build produced nothing, regardless of what actually happened; in a
case reproduced from the owner log all three were false and the real cause was
not even listed. The "Checking your will" row had the same flaw, showing one
sentence ("Found CHANGES to the DATE or the HEIRS") for five situations,
including one where it is plainly wrong (funds received).

core/heirs.py: record WHY buildTransactions gave up in a new last_build_error
attribute (8 reason codes), set at each path that previously returned empty
with no explanation, plus a processed_willexecutors counter to tell "every
will-executor was skipped" apart from "we tried and failed". Also fix a latent
crash in the prepare_transactions handler, which read a no-longer-existing
e.heirname attribute and re-raised the resulting AttributeError, masking the
real error.

gui/qt/dialogs.py: add msg_alert() (amber warning sign, body text in the theme
colour, readable in both themes), _build_failure_message() and
_check_failure_message() to turn those causes into one precise sentence each,
with an honest "cause could not be determined" fallback. Catch
BalanceTooLowException, which already carried the figures but fell through to
the generic red technical error.

No new exception classes were introduced (owner request): the plain
NotCompleteWillException cases are told apart structurally, not by text.

Name the real cause of a failed build instead of guessing

Why

The Building Will report had two problems the owner hit in practice:

  1. The long "could not build the will" block was printed entirely in amber,
    which made it hard to read.
  2. Whenever the build produced nothing, the dialog printed a fixed list of
    three "possible reasons"
    (low balance / dust shares / check-alive later
    than the delivery date) regardless of what actually happened. In a case
    reproduced from the owner's Electrum log all three were false, and the
    real cause (no delivery date left to build) was not even in the list.
  3. The Checking your will row had the same flaw: the single sentence
    "Found CHANGES to the DATE or the HEIRS" was shown for five different
    situations — including one where it is plainly wrong (funds received, where
    neither the date nor the heirs changed).

What this does

bal/core/heirs.py

  • New Heirs.last_build_error, recording why buildTransactions produced no
    transaction. Reset at the start of every build and set at each path that
    previously returned empty with no explanation: NO_HEIRS, NO_UTXO,
    NO_WILLEXECUTOR_USABLE, NO_FUTURE_DATE, WILLEXECUTOR_FEE,
    WILLEXECUTOR_FEE_TOO_HIGH, TX_BUILD_FAILED, WILLEXECUTOR_TX_ERROR.
  • New processed_willexecutors counter, so "every will-executor was skipped"
    (which returned silently, with no log line at all) is told apart from "we
    tried and the build failed".
  • Bug fix: the prepare_transactions exception handler read e.heirname
    to auto-deselect the offending will-executor, but nothing in the plugin sets
    that attribute any more. The lookup raised AttributeError, and the inner
    except Exception: raise re-raised that, aborting the whole build with a
    confusing secondary error. It now records the reason, logs the real
    exception with the will-executor URL, and moves on to the next one.

bal/gui/qt/dialogs.py

  • New msg_alert() — amber warning sign, body text in the theme's default
    colour. Colour attracts attention, it is not what gets read, so it stays on
    the sign alone; this also keeps the text readable under the dark theme,
    where a hard-coded black would disappear.
  • New _build_failure_message() and _check_failure_message() — turn the
    causes above into one precise sentence each, with an honest "the exact cause
    could not be determined" fallback rather than three guesses.
  • New except BalanceTooLowException handler — the exception already carried
    balance, fees and dust threshold, but fell through to the generic handler
    which printed the raw technical string in red and re-raised.
  • "Checking variables": No Heirs uses the new style; "Check Alive Threshold
    Passed" deliberately stays red, being the more urgent case (owner
    request).

bal/gui/qt/common.py — re-export BalanceTooLowException.

No new exception classes were introduced (owner request): the two plain
NotCompleteWillException cases are told apart structurally (raised with no
argument vs. with one), not by matching message text.

Verification

  • py_compile clean on all 44 files of the package.
  • msg_alert, _build_failure_message and _check_failure_message were
    extracted from the source via AST and executed against every reason code and
    every exception type, with the exception hierarchy rebuilt from will.py:
    9 build cases and 8 check cases all produce the intended text.
  • NOT run: the official test suite — the Windows machine used for this work
    has no importable electrum module.
  • Manually tested by the owner in Electrum 4.8.1: NO_FUTURE_DATE,
    WILLEXECUTOR_FEE and No Heirs all confirmed on screen.

Merge notes

  • Merges cleanly into main (no conflicts).
  • Against feature/bal-qr-transfer there is one trivial conflict, in
    CHANGELOG.md only
    — both branches append an entry at the end of the file.
    This branch deliberately numbers its entry 57, since the QR branch uses
    56, so the resolution is simply to keep both in order.
  • bal/gui/qt/dialogs.py merges cleanly with the QR branch, including the
    import list.
  • Does not touch bal/core/will.py, so it does not interfere with the
    in-progress RLock / cannot pickle '_thread.RLock' object fix.
The Building Will report showed a fixed list of three "possible reasons" whenever a build produced nothing, regardless of what actually happened; in a case reproduced from the owner log all three were false and the real cause was not even listed. The "Checking your will" row had the same flaw, showing one sentence ("Found CHANGES to the DATE or the HEIRS") for five situations, including one where it is plainly wrong (funds received). core/heirs.py: record WHY buildTransactions gave up in a new last_build_error attribute (8 reason codes), set at each path that previously returned empty with no explanation, plus a processed_willexecutors counter to tell "every will-executor was skipped" apart from "we tried and failed". Also fix a latent crash in the prepare_transactions handler, which read a no-longer-existing e.heirname attribute and re-raised the resulting AttributeError, masking the real error. gui/qt/dialogs.py: add msg_alert() (amber warning sign, body text in the theme colour, readable in both themes), _build_failure_message() and _check_failure_message() to turn those causes into one precise sentence each, with an honest "cause could not be determined" fallback. Catch BalanceTooLowException, which already carried the figures but fell through to the generic red technical error. No new exception classes were introduced (owner request): the plain NotCompleteWillException cases are told apart structurally, not by text. # Name the real cause of a failed build instead of guessing ## Why The **Building Will** report had two problems the owner hit in practice: 1. The long "could not build the will" block was printed entirely in amber, which made it hard to read. 2. Whenever the build produced nothing, the dialog printed a **fixed list of three "possible reasons"** (low balance / dust shares / check-alive later than the delivery date) regardless of what actually happened. In a case reproduced from the owner's Electrum log **all three were false**, and the real cause (no delivery date left to build) was not even in the list. 3. The **Checking your will** row had the same flaw: the single sentence "Found CHANGES to the DATE or the HEIRS" was shown for five different situations — including one where it is plainly wrong (funds received, where neither the date nor the heirs changed). ## What this does **`bal/core/heirs.py`** - New `Heirs.last_build_error`, recording *why* `buildTransactions` produced no transaction. Reset at the start of every build and set at each path that previously returned empty with no explanation: `NO_HEIRS`, `NO_UTXO`, `NO_WILLEXECUTOR_USABLE`, `NO_FUTURE_DATE`, `WILLEXECUTOR_FEE`, `WILLEXECUTOR_FEE_TOO_HIGH`, `TX_BUILD_FAILED`, `WILLEXECUTOR_TX_ERROR`. - New `processed_willexecutors` counter, so "every will-executor was skipped" (which returned silently, with no log line at all) is told apart from "we tried and the build failed". - **Bug fix:** the `prepare_transactions` exception handler read `e.heirname` to auto-deselect the offending will-executor, but nothing in the plugin sets that attribute any more. The lookup raised `AttributeError`, and the inner `except Exception: raise` re-raised *that*, aborting the whole build with a confusing secondary error. It now records the reason, logs the real exception with the will-executor URL, and moves on to the next one. **`bal/gui/qt/dialogs.py`** - New `msg_alert()` — amber warning sign, body text in the theme's default colour. Colour attracts attention, it is not what gets read, so it stays on the sign alone; this also keeps the text readable under the dark theme, where a hard-coded black would disappear. - New `_build_failure_message()` and `_check_failure_message()` — turn the causes above into one precise sentence each, with an honest "the exact cause could not be determined" fallback rather than three guesses. - New `except BalanceTooLowException` handler — the exception already carried balance, fees and dust threshold, but fell through to the generic handler which printed the raw technical string in red and re-raised. - "Checking variables": `No Heirs` uses the new style; "Check Alive Threshold Passed" deliberately **stays red**, being the more urgent case (owner request). **`bal/gui/qt/common.py`** — re-export `BalanceTooLowException`. **No new exception classes were introduced** (owner request): the two plain `NotCompleteWillException` cases are told apart *structurally* (raised with no argument vs. with one), not by matching message text. ## Verification - `py_compile` clean on all 44 files of the package. - `msg_alert`, `_build_failure_message` and `_check_failure_message` were extracted from the source via AST and executed against every reason code and every exception type, with the exception hierarchy rebuilt from `will.py`: **9 build cases and 8 check cases** all produce the intended text. - **NOT run:** the official test suite — the Windows machine used for this work has no importable `electrum` module. - Manually tested by the owner in **Electrum 4.8.1**: `NO_FUTURE_DATE`, `WILLEXECUTOR_FEE` and `No Heirs` all confirmed on screen. ## Merge notes - Merges **cleanly into `main`** (no conflicts). - Against `feature/bal-qr-transfer` there is **one trivial conflict, in `CHANGELOG.md` only** — both branches append an entry at the end of the file. This branch deliberately numbers its entry **57**, since the QR branch uses **56**, so the resolution is simply to keep both in order. - `bal/gui/qt/dialogs.py` merges cleanly with the QR branch, including the import list. - Does **not** touch `bal/core/will.py`, so it does not interfere with the in-progress RLock / `cannot pickle '_thread.RLock' object` fix.
bitcoinafterlife added 1 commit 2026-09-04 10:29:42 +00:00
The Building Will report showed a fixed list of three "possible reasons"
whenever a build produced nothing, regardless of what actually happened; in a
case reproduced from the owner log all three were false and the real cause was
not even listed. The "Checking your will" row had the same flaw, showing one
sentence ("Found CHANGES to the DATE or the HEIRS") for five situations,
including one where it is plainly wrong (funds received).

core/heirs.py: record WHY buildTransactions gave up in a new last_build_error
attribute (8 reason codes), set at each path that previously returned empty
with no explanation, plus a processed_willexecutors counter to tell "every
will-executor was skipped" apart from "we tried and failed". Also fix a latent
crash in the prepare_transactions handler, which read a no-longer-existing
e.heirname attribute and re-raised the resulting AttributeError, masking the
real error.

gui/qt/dialogs.py: add msg_alert() (amber warning sign, body text in the theme
colour, readable in both themes), _build_failure_message() and
_check_failure_message() to turn those causes into one precise sentence each,
with an honest "cause could not be determined" fallback. Catch
BalanceTooLowException, which already carried the figures but fell through to
the generic red technical error.

No new exception classes were introduced (owner request): the plain
NotCompleteWillException cases are told apart structurally, not by text.
bitcoinafterlife merged commit c8ddf66ccb into main 2026-09-09 12:31:28 +00:00
bitcoinafterlife deleted branch ui/build-will-error-messages 2026-09-09 12:31:48 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bitcoinafterlife/bal-electrum-plugin#7