fix(mesh): capture actual esptool/rnodeconf output in the failure error

run_streamed's failure path only reported "Command exited with exit status:
N" — the real stderr (already captured line-by-line into job.log_tail for
the UI's live poll) never made it into the error that gets logged to
journald. A real esptool failure just now showed only the bare exit code,
with esptool's actual error text sitting in-memory, visible in the UI but
not diagnosable from the server logs.

Now includes the last 10 log_tail lines in the returned error, so the
actual tool output shows up in journalctl too.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
ssmithx 2026-07-23 02:51:58 +00:00
parent 39e88529b3
commit ff532465cf

View File

@ -838,7 +838,23 @@ async fn run_streamed(mut cmd: Command, stdin: Option<Vec<u8>>, job: &Arc<FlashJ
let _ = t.await;
}
if !status.success() {
anyhow::bail!("Command exited with {status}");
// Exit status alone isn't diagnosable — the actual esptool/rnodeconf
// stderr (already captured into job.log_tail by the reader tasks
// above) is what actually explains a failure. Confirmed live
// 2026-07-23: a bare "Command exited with exit status: 1" told us
// nothing when esptool's real error was sitting in the log tail the
// whole time, only visible via the UI's live poll, not journald.
let tail: Vec<String> = job
.snapshot()
.await
.log_tail
.iter()
.rev()
.take(10)
.rev()
.cloned()
.collect();
anyhow::bail!("Command exited with {status}\n{}", tail.join("\n"));
}
Ok(())
}