Handle command spawn failures more gracefully

This commit is contained in:
Austen Adler 2022-12-16 23:44:35 -05:00
parent 416911a337
commit a3027a3d6d
2 changed files with 32 additions and 18 deletions

View File

@ -1,3 +1,6 @@
use anyhow::bail;
use anyhow::Context;
use anyhow::Result;
use std::{ use std::{
io::Write, io::Write,
process::{Command, Stdio}, process::{Command, Stdio},
@ -22,15 +25,21 @@ impl Default for CommandResult {
} }
pub fn run(app: &mut App) { pub fn run(app: &mut App) {
app.command_result = match run_inner(app) {
Ok(c) => c,
Err(e) => CommandResult {
status_success: false,
stdout: vec![],
stderr: format!("{e:?}").as_bytes().to_vec(),
},
};
}
fn run_inner(app: &mut App) -> Result<CommandResult> {
let args = match shellwords::split(&app.cmdline) { let args = match shellwords::split(&app.cmdline) {
Ok(a) => a, Ok(a) => a,
Err(e) => { Err(e) => {
app.command_result = CommandResult { bail!("Argument error: {e:?}");
status_success: false,
stdout: vec![],
stderr: format!("Argument error: {e:?}").as_bytes().to_vec(),
};
return;
} }
}; };
@ -41,22 +50,20 @@ pub fn run(app: &mut App) {
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.spawn() .spawn()
.expect("Could not spawn child process"); .context("Could not spawn child process")?;
let mut stdin = child.stdin.take().expect("Could not take stdin"); let mut stdin = child.stdin.take().context("Could not take stdin")?;
let text_orig_clone = app.text_orig.clone(); let text_orig_clone = app.text_orig.clone();
std::thread::spawn(move || { std::thread::spawn(move || {
stdin let _ = stdin.write_all(text_orig_clone.as_bytes());
.write_all(text_orig_clone.as_bytes())
.expect("Failed to write to stdin");
}); });
// Collect the output // Collect the output
let output = child.wait_with_output().expect("Failed to read stdout"); let output = child.wait_with_output().context("Failed to read stdout")?;
app.command_result = CommandResult { Ok(CommandResult {
status_success: output.status.success(), status_success: output.status.success(),
stdout: output.stdout, stdout: output.stdout,
stderr: output.stderr, stderr: output.stderr,
} })
} }

View File

@ -107,8 +107,8 @@ impl App {
hidden_options: vec![], hidden_options: vec![],
}, },
Template::Perl => Self { Template::Perl => Self {
cmdline: String::from("-p -e 's/./_/'"), cmdline: String::from("-p -e 's///'"),
cmdline_position: 3_u16, cmdline_position: 10_u16,
text_orig, text_orig,
command_result: CommandResult::default(), command_result: CommandResult::default(),
autorun: true, autorun: true,
@ -292,8 +292,15 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
chunks[0], chunks[0],
); );
f.render_widget( f.render_widget(
Paragraph::new(app.cmdline.as_ref()) Paragraph::new(app.cmdline.as_ref()).block(
.block(Block::default().title("Cmdline").borders(Borders::ALL)), Block::default()
.title(format!(
"Cmdline ({} {})",
app.command,
app.hidden_options.join(" ")
))
.borders(Borders::ALL),
),
vertical_chunks[1], vertical_chunks[1],
); );