fix: guard every machine_npub deref against unpaired machines (None)
Some checks failed
ci.yml / fix: guard every machine_npub deref against unpaired machines (None) (pull_request) Failing after 0s
Some checks failed
ci.yml / fix: guard every machine_npub deref against unpaired machines (None) (pull_request) Failing after 0s
machine_npub became nullable in #29/m011 (register-unpaired flow), but several consumers still assumed it's non-None and crashed `normalize_public_key(None)` with `AttributeError: 'NoneType' object has no attribute 'startswith'`. On the demo (which had an unpaired machine) this broke the platform-fee update (500) and spammed the cassette consumer with errors every 2s. The #29 create/pair paths were guarded; these were missed: - views_api `api_update_super_config`: the "republish fee to every active machine" loop → skip unpaired (they get their config at pairing). - cassette_transport `build_state_d_tags_for_machines`: skip unpaired (no state-beacon d-tag yet) — the cassette-consumer loop crash. - crud `get_machine_by_atm_pubkey_hex`: its `except (ValueError, AssertionError)` didn't catch the AttributeError; skip unpaired before normalize — the cassette event-handler crash. - bitspire `assert_nostr_attribution`: reject (SettlementAttributionError) an unpaired machine instead of crashing the payment listener. - views_api cassettes/publish endpoint: 400 (not paired) instead of crashing publish_to_atm. Verified on the dev stack: with an unpaired active machine present, the cassette consumer registers (skipping it) and runs clean — no AttributeError.
This commit is contained in:
parent
622c1be5d3
commit
d52a3bfafe
4 changed files with 31 additions and 2 deletions
14
views_api.py
14
views_api.py
|
|
@ -1081,6 +1081,12 @@ async def api_update_super_config(
|
|||
)
|
||||
if super_fractions_changed:
|
||||
for machine in await list_all_active_machines():
|
||||
# Unpaired machines (machine_npub is None — nullable since #29/m011)
|
||||
# have no Nostr identity to publish a fee-config beacon to. Skip
|
||||
# them; they pick up the current fee config when they pair
|
||||
# (api_pair_machine publishes on success).
|
||||
if not machine.machine_npub:
|
||||
continue
|
||||
await publish_fee_config(machine, config, machine.operator_user_id)
|
||||
return config
|
||||
|
||||
|
|
@ -1147,6 +1153,14 @@ async def api_publish_machine_cassettes(
|
|||
500 — anything else from the publish path
|
||||
"""
|
||||
machine = await _machine_owned_by(machine_id, user.id)
|
||||
if not machine.machine_npub:
|
||||
# Unpaired machine (machine_npub None — nullable since #29/m011) has no
|
||||
# ATM identity to publish a cassette config to. Fail fast with a clean
|
||||
# 400 instead of crashing publish_to_atm's normalize_public_key(None).
|
||||
raise HTTPException(
|
||||
HTTPStatus.BAD_REQUEST,
|
||||
"machine is not paired — pair it before publishing cassette config",
|
||||
)
|
||||
|
||||
existing = await list_cassette_configs_for_machine(machine_id)
|
||||
existing_positions = {row.position for row in existing}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue