Skip to content

std::process::Command output() method error handling hazards #73126

Description

@ijackson

Hi. Normally, Rust makes it difficult to accidentally write buggy code. This is one of its great strengths. However, the API of output() on std::process::Command API has two serious error handling hazards:

  1. It requires the user to explicitly fish out the program's exit status and check it.
  2. It requires the user to explicitly deal, somehow, with the program's stderr output (if any).

See the example below.

I think this is very difficult to fix with the current return value from output(). It seems to me that there should be a new function whose behaviour is as follows:

  • Unless the user explictly called .stderr(...) when building the Command, any nonempty stderr is treated as an error, giving an Err return value (whose Debug impl prints the stderr output).
  • Nonzero exit status is treated as an error, giving an Err return value,
  • In case of nonzero exit status together with nonempty stderr output (the usual case) the error object contains both (and its Debug impl displays both).
  • The returned value is purely the actual stdout.

I don't know what this should be called. Unfortunately the name output has been taken for the more hazardous, raw, function. Which we must retain because if you want to run a command that sometimes succeeds returning nonzero (eg, diff) you need something like it.

(See also #70186 which is about the return value from spawn(). I am about to file another issue about the return value from wait())

use std::process::*;
use std::io::stdout;
use std::io::Write;

fn main() {
    let command = ["ls","--no-such-option"];
    
    let output = Command::new(command[0])
                     .args(&command[1..])
                     .output()
                     .expect("output() failed");
    println!("Output from {:?}:", &command);
    stdout().write_all(output.stdout.as_slice()).expect("write failed");
    
    println!("All went well!")
}

(Playground)

Actual output:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.72s
     Running `target/debug/playground`

Standard Output

Output from ["ls", "--no-such-option"]:
All went well!

Expected output:

Some kind of compiler warning. Or something in the docs to say not to use .output() (and, therefore, something convenient to use instead).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-processArea: `std::process` and `std::env`C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-libs-api[DEPRECATED; DO NOT USE]

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions