sendErrorPrecedesPersistence function

bool sendErrorPrecedesPersistence(
  1. Object error
)

Whether error, thrown by the SDK's own send AFTER the spend closure was entered, is a kind the core raises only BEFORE any transaction is persisted (S7 U1 fold) — so classifySendFailure's "nothing was sent" / back-to-form routing is still the truth. Anything else lands on SendOutcomeUnknown.

Each kind was checked against the core's send path (Wallet::send_by_id → sign_proposal_upstream → broadcast_persisted):

  • WatchOnly — require_spend_capable, before the token is touched.
  • WalletBusy — require_open at the top of sign_proposal_upstream.
  • NetworkUpgradeUnsupported, ConsensusGraceExpired, ConsensusNotEvaluated — signing_permit, before the seed pull.
  • ProposalAlreadyUsed, ProposalStale — the registry peek/consume and assert_proposal_anchor_fresh, before the create; ProposalStale is also map_create_err's anchor arm, a create that rolled back.
  • SeedRequired, SeedMismatch — acquire_seed and ensure_seed_controls_account, before the token is consumed.
  • QueuedSendsFull — the two-step enrol's enqueue, before the create.
  • TexSendLimitReached, SignFailed — map_create_err only, a create the engine rolled back whole.

NOT listed, on purpose: StoreCorrupt (raw_tx_bytes in broadcast_persisted reads the just-persisted bytes; the two-step's mark_sent_multi runs after the create committed), and DiskFull, StoreBusy, Io — the same mark_sent_multi write classifies a SQLite fault into any of them after the transactions exist. InvalidState is broadcast_persisted's answer for a wallet wiped mid-send, also after.

Implementation

bool sendErrorPrecedesPersistence(Object error) =>
    error is WalletApiError &&
    switch (error.kind) {
      WalletErrorKind_WatchOnly() ||
      WalletErrorKind_WalletBusy() ||
      WalletErrorKind_NetworkUpgradeUnsupported() ||
      WalletErrorKind_ConsensusGraceExpired() ||
      WalletErrorKind_ConsensusNotEvaluated() ||
      WalletErrorKind_ProposalAlreadyUsed() ||
      WalletErrorKind_ProposalStale() ||
      WalletErrorKind_SeedRequired() ||
      WalletErrorKind_SeedMismatch() ||
      WalletErrorKind_QueuedSendsFull() ||
      WalletErrorKind_TexSendLimitReached() ||
      WalletErrorKind_SignFailed() => true,
      _ => false,
    };