use crate::errors::AppError;
use std::process::Output;
pub struct ErrorPropagator {
pub binary: String,
pub args: Vec<String>,
}
impl ErrorPropagator {
pub fn new(binary: impl Into<String>, args: Vec<String>) -> Self {
Self {
binary: binary.into(),
args,
}
}
pub fn propagate(&self, output: &Output) -> Result<(), AppError> {
if output.status.success() {
return Ok(());
}
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let code = output.status.code().unwrap_or(-1);
let mut msg = format!("{} exited with code {}", self.binary, code);
if !stderr.trim().is_empty() {
msg.push_str(&format!("\nstderr: {}", stderr.trim()));
}
if !stdout.trim().is_empty() {
msg.push_str(&format!("\nstdout: {}", stdout.trim()));
}
msg.push_str(&format!("\nargs: {}", self.args.join(" ")));
Err(AppError::Internal(anyhow::anyhow!(msg)))
}
pub fn require_success(&self, output: &Output) -> Result<String, AppError> {
self.propagate(output)?;
Ok(String::from_utf8_lossy(&output.stdout).into_owned())
}
}