Backport error handling patterns from legacy lamassu-machine #34
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
An audit of lamassu-next's error handling vs the legacy lamassu-machine codebase reveals significant gaps. The legacy code is battle-tested with patterns we should backport.
Critical Problems in lamassu-next
Severity 1 — Data Loss / Safety
machine.ts:676-687)stackBill()has zero error handling:main.ts:199-208sends serial command with no verification. If serial is dead, bill stays in escrow, renderer thinks it was stacked.Severity 2 — Data Inconsistency
hal-service.ts:139-141)initErrorshows maintenance screen. Mid-transaction hardware failures are console.log only.billsPresent()returnstruealways,waitForBillsRemoved()returns immediately.Patterns to Backport from Legacy
1. Heartbeat / Watchdog
Legacy:
watchdog.js+brain.js:439-472— Unix socket heartbeat, pings every 10s. External supervisor detects hangs and restarts.lamassu-next: Nothing. If the process hangs, it stays hung.
2. Dispenser Auto-Reinit on Failure
Legacy:
brain.js:4062-4077— If dispense fails, reinitializes dispenser after 200ms and retries.lamassu-next: Closes connection, never reconnects.
3. Error Throttling
Legacy:
id003.js:17—_.throttle(2000, err => this.emit('error', err))prevents error spam.lamassu-next: Fires every error raw, can crash renderer.
4. Network State Awareness
Legacy:
brain.js:2783-2842— Distinguishes "safe to pause" (no bills) vs "forced transition" (mid-tx).processPending()resumes interrupted transactions.lamassu-next: No network state machine. Disconnection = frozen.
5. Batch Dispense with Checkpoints
Legacy:
brain.js:4085-4118— Waits for bill removal between batches, shows progress, stops on first error.lamassu-next: All-or-nothing dispense.
6. Persistent Disk Logging
Legacy:
logs.js— JSON logs with UUID + timestamp, survives crashes, queryable after-the-fact.lamassu-next: Only
console.log(lost on restart).7. Operator Alerts / Maintenance State
Legacy:
brain.js:3490-3493— DedicatedactionRequiredMaintenancestate. Cashbox removal notification with receipt printing (brain.js:3356-3358).lamassu-next: No operator notification mechanism.
Proposed Implementation Order
Comparison Table
References
lamassu-machine/lib/brain.js(4318 lines)apps/machine/electron/hal-service.tspackages/state-machine/src/machine.tsapps/machine/electron/main.tsStatus check against current
dev(2026-07-04 review) — several Severity-1 claims are now outdated, others confirmed still live:Outdated (already fixed on dev):
dispense_error/partialstatus including per-cassette results (stores/atm.tsdispenseError subscriber), republishes cassette state to the operator, and the remediation path exists (operator command queue → manual dispense →remediatewithref_txidinelectron/main.ts). Remaining gap: no push alert to the operator — discovery is via dashboard/DB.stackBill()has zero error handling" — addressed by PR #77: credit now waits for the validator'sbillsValidstacked-confirmation; a stack that fails or returns the bill never credits (billsRejectedclears the in-flight marker).Confirmed still live:
onHalErrorsends{type: 'ERROR'}and no state in the machine handles it (zeroERROR:handlers inmachine.ts). Validator disconnect/stacker-open mid-transaction is a dead-letter. Legacy_billValidatorErrdisables the validator and pushes a send-only screen with current credit;stackerOpennotifies the server (brain.js:3890–3905,:3379atc0b69d1).DISPENSE_TIMEOUT120s) butdispenseErrorauto-idles after 30s with no operator override/retry.Also worth folding in from the same review:
persistTransactionfailures are log-and-forget (no retry/queue), and abandoned cash-in (bills stacked, thenconfirmAbandon → idle) records no transaction and no cashbox increment — physical cashbox silently diverges fromstate.db.