From f40f7a5aeb457dd6888d8291792ce224a922d52b Mon Sep 17 00:00:00 2001 From: Moritz Hedtke Date: Tue, 24 Jun 2025 02:20:25 +0200 Subject: [PATCH] Add better error handling for wasm-opt and prevent file truncation on error (#4313) * Add better error handling for wasm-opt and prevent file truncation on error * clippy --------- Co-authored-by: Jonathan Kelley --- packages/cli/src/wasm_opt.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/wasm_opt.rs b/packages/cli/src/wasm_opt.rs index f41d4f45d..180b901e6 100644 --- a/packages/cli/src/wasm_opt.rs +++ b/packages/cli/src/wasm_opt.rs @@ -1,6 +1,7 @@ use anyhow::{anyhow, Context}; use flate2::read::GzDecoder; use tar::Archive; +use tempfile::NamedTempFile; use tokio::fs; use crate::config::WasmOptLevel; @@ -24,6 +25,7 @@ pub async fn optimize(input_path: &Path, output_path: &Path, cfg: &WasmOptConfig struct WasmOpt { path: PathBuf, input_path: PathBuf, + temporary_output_path: NamedTempFile, output_path: PathBuf, cfg: WasmOptConfig, } @@ -38,6 +40,7 @@ impl WasmOpt { Ok(Self { path, input_path: input_path.to_path_buf(), + temporary_output_path: tempfile::NamedTempFile::new()?, output_path: output_path.to_path_buf(), cfg: cfg.clone(), }) @@ -80,12 +83,20 @@ impl WasmOpt { WasmOptLevel::Four => "-O4", }; + tracing::debug!( + "Running wasm-opt: {} {} {} -o {} {}", + self.path.to_string_lossy(), + self.input_path.to_string_lossy(), + level, + self.temporary_output_path.path().to_string_lossy(), + args.join(" ") + ); let mut command = tokio::process::Command::new(&self.path); command .arg(&self.input_path) .arg(level) .arg("-o") - .arg(&self.output_path) + .arg(self.temporary_output_path.path()) .args(args); command } @@ -96,7 +107,18 @@ impl WasmOpt { if !res.status.success() { let err = String::from_utf8_lossy(&res.stderr); - tracing::error!("wasm-opt failed with status code {}: {}", res.status, err); + tracing::error!( + "wasm-opt failed with status code {}\nstderr: {}\nstdout: {}", + res.status, + err, + String::from_utf8_lossy(&res.stdout) + ); + // A failing wasm-opt execution may leave behind an empty file so copy the original file instead. + if self.input_path != self.output_path { + std::fs::copy(&self.input_path, &self.output_path).unwrap(); + } + } else { + std::fs::copy(self.temporary_output_path.path(), &self.output_path).unwrap(); } Ok(())