Handle command spawn failures more gracefully
This commit is contained in:
parent
416911a337
commit
a3027a3d6d
@ -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,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
15
src/main.rs
15
src/main.rs
@ -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],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user