From a832b53a1af5301e9088e2e10d201fc264f71f6d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 23 May 2024 16:28:53 +0200 Subject: [PATCH] Make non-UTF8 stdout/stderr from nodes non-fatal Log a warning instead and do a lossy conversion to String. This ensures that `stdout`/`stderr` stay open, which avoids a `SIGPIPE` exit of the node on the next println. --- binaries/daemon/src/spawn.rs | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/binaries/daemon/src/spawn.rs b/binaries/daemon/src/spawn.rs index 0dc353de..8dd59f67 100644 --- a/binaries/daemon/src/spawn.rs +++ b/binaries/daemon/src/spawn.rs @@ -272,16 +272,29 @@ pub async fn spawn_node( let mut buffer = String::new(); let mut finished = false; while !finished { + let mut raw = Vec::new(); finished = match child_stdout - .read_line(&mut buffer) + .read_until(b'\n', &mut raw) .await - .wrap_err("failed to read stdout line from spawned node") + .wrap_err_with(|| format!("failed to read stdout line from spawned node {node_id}")) { Ok(0) => true, Ok(_) => false, Err(err) => { tracing::warn!("{err:?}"); - true + false + } + }; + + match String::from_utf8(raw) { + Ok(s) => buffer.push_str(&s), + Err(err) => { + let lossy = String::from_utf8_lossy(err.as_bytes()); + tracing::warn!( + "stdout not valid UTF-8 string (node {node_id}): {}: {lossy}", + err.utf8_error() + ); + buffer.push_str(&lossy) } }; @@ -319,10 +332,11 @@ pub async fn spawn_node( let mut buffer = String::new(); let mut finished = false; while !finished { + let mut raw = Vec::new(); finished = match child_stderr - .read_line(&mut buffer) + .read_until(b'\n', &mut raw) .await - .wrap_err("failed to read stderr line from spawned node") + .wrap_err_with(|| format!("failed to read stderr line from spawned node {node_id}")) { Ok(0) => true, Ok(_) => false, @@ -332,6 +346,18 @@ pub async fn spawn_node( } }; + match String::from_utf8(raw) { + Ok(s) => buffer.push_str(&s), + Err(err) => { + let lossy = String::from_utf8_lossy(err.as_bytes()); + tracing::warn!( + "stderr not valid UTF-8 string (node {node_id}): {}: {lossy}", + err.utf8_error() + ); + buffer.push_str(&lossy) + } + }; + if buffer.starts_with("Traceback (most recent call last):") { if !finished { continue;