diff --git a/core/archipelago/src/api/rpc/middleware.rs b/core/archipelago/src/api/rpc/middleware.rs index 7489f51b..ac029f36 100644 --- a/core/archipelago/src/api/rpc/middleware.rs +++ b/core/archipelago/src/api/rpc/middleware.rs @@ -66,6 +66,9 @@ pub(super) fn sanitize_error_message(msg: &str) -> String { "Bitcoin address", "No router", "No OpenWrt", + "No space left", + "TollGate installation failed", + "No pre-built TollGate", ]; for prefix in &user_facing_prefixes { if msg.starts_with(prefix) { diff --git a/core/openwrt/src/tollgate/install.rs b/core/openwrt/src/tollgate/install.rs index 4b1beb81..64b9a5e6 100644 --- a/core/openwrt/src/tollgate/install.rs +++ b/core/openwrt/src/tollgate/install.rs @@ -48,8 +48,27 @@ pub fn install_tollgate(router: &Router) -> Result<()> { info!("[{}] Downloading TollGate for {} from GitHub releases", router.host, arch); router.run_ok(&format!("wget -O /tmp/tollgate.ipk '{}'", url))?; - router.run_ok("opkg install --force-depends /tmp/tollgate.ipk")?; + + // Capture stderr too — BusyBox opkg exits 0 even on "Cannot install" failures. + let (out, _code) = router.run("opkg install --force-depends /tmp/tollgate.ipk 2>&1")?; router.run_ok("rm -f /tmp/tollgate.ipk")?; + if out.contains("Cannot install") || out.contains("errors encountered") { + if out.contains("Only have") && out.contains("available on filesystem") { + // Extract the sizes from the error for a user-readable message. + // Example: "Only have 8884kb available on filesystem /overlay, pkg tollgate-wrt needs 18750" + anyhow::bail!( + "No space left on router for TollGate ({}). \ + This router has insufficient flash storage. \ + Consider a router with ≥32 MB flash or add an extroot USB drive.", + out.lines() + .find(|l| l.contains("Only have")) + .unwrap_or("check router disk space") + .trim() + ); + } + anyhow::bail!("TollGate installation failed: {}", out.trim()); + } + Ok(()) }