fix(rpc): surface unknown-method + RNode settings errors instead of masking

Deploying the .126 LoRa panel ahead of its daemon made every button
report "Operation failed. Check server logs for details." — the panel
was calling RPCs the older binary doesn't have, and the sanitizer
masked "Unknown method: mesh.rnode-config" into that generic string.
Read as "the feature is broken" rather than "this node needs its
update" (operator, 2026-08-06).

Allowlisted: "Unknown method" (a frontend newer than its daemon should
say so), every RNode RF validation message (each names the field and
its legal range — the entire point of validating before touching the
radio), and the actionable mesh preconditions (no device connected,
mesh service not running, MeshCore has no remote reboot, radio daemon
did not answer, RNode interface disabled).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-06 09:28:44 -04:00
co-authored by Claude Fable 5
parent 6c0fc366b3
commit 3e124dd4b3
@@ -84,6 +84,33 @@ pub(super) fn sanitize_error_message(msg: &str) -> String {
// Masking sent the operator to journalctl again (framework-pt
// sweep, 2026-08-06) — same lesson as the two above.
"Failed to send",
// A frontend newer than the daemon calls methods it doesn't have.
// Masked, this reads as "the feature is broken" instead of "this
// node needs its update" — hit live the moment the .126 LoRa panel
// was deployed ahead of its binary (2026-08-06).
"Unknown method",
// RNode RF settings validation (mesh::rnode_settings::validate) —
// every one names the offending field and its legal range, which is
// the entire point of validating before touching the radio.
"frequency ",
"bandwidth ",
"spreading factor ",
"coding rate ",
"tx power ",
"airtime_limit_short",
"airtime_limit_long",
"port must be an absolute",
"Invalid settings",
"Missing 'settings'",
// Mesh preconditions the operator can act on directly.
"Mesh service not running",
"No mesh device connected",
"Mesh listener not running",
"MeshCore radios have no remote reboot",
"Radio state read-back",
"The radio daemon did not answer",
"The radio did not acknowledge",
"RNode interface is disabled",
// Lightning payment failures carry LND's reason ("invoice expired.
// Valid until …", "no route", …) — the user can act on every one of
// them, and masking sent the operator to journalctl (invoice-expired