duct.rs icon indicating copy to clipboard operation
duct.rs copied to clipboard

Add a way to get stdout/err from processes that exit with a non-zero status

Open sunshowers opened this issue 4 years ago • 2 comments

This can be done through use of unchecked today, but it would be great to have an ergonomic way to do so given how much duct is built around making the correct thing easier to do.

The main challenge is that wait() etc return a &Output, while Rust errors are generally 'static. stdout and stderr are unbounded so if we clone data, it can be quite expensive.

Some thoughts:

  • allow opting into printing out stdout/stderr, have it turned off by default
  • as part of opting in, specify a beginning and end length, truncating the output in the middle
  • the data is UTF-8 in many cases, but it might not be, have some handling around that:
    • truncation will need special handling around multibyte UTF-8 sequences given that the main purpose is to print out data
    • assume that if someone's asking for output to be returned, they generally expect it to be UTF-8 and just use String::from_utf8_lossy while printing the data out
  • use a custom error type for clients that care about it, and add a conversion to io::Error through a From impl for compatibility

sunshowers avatar Sep 12 '21 22:09 sunshowers

Could you give me an example of what you're imagining the API might look like, and compare that to doing the same thing with unchecked today?

oconnor663 avatar Sep 13 '21 01:09 oconnor663

Digging up this thread - I want to run a command that will print its errors to stderr. I'd love to be able to do something like

let result = cmd!(...).run();
match result {
  Ok(output) => { ... },
  Error(err) => {
	eprintln!("{}", err.stderr);
    // ...
  },
}

// vs unchecked

let result = cmd!(...).unchecked().run()?;
if result.status.success() { ... }
else {
	eprintln!("{}", err.stderr);
}

It's definitely doable via unchecked but as OP said duct is about doing commands the right way. To me, at least, dropping the (likely) root cause error messages from the command when the command fails by default seems wrong? To me at least I think that the rare case is wanting to just tell the user "this command failed" as opposed to "this command failed and here's why".

bradzacher avatar Jan 25 '24 12:01 bradzacher