Skip to content

[clap_complete] use of expect causes panic since writing to stdout may fail #5993

@gtema

Description

@gtema

Please complete the following tasks

Rust Version

1.86

Clap Version

4.5.50

Minimal reproducible code

#[derive(Parser, Debug, PartialEq)]
#[command(name = "completion-derive")]
struct Opt {
    // If provided, outputs the completion file for given shell
    #[arg(long = "generate", value_enum)]
    generator: Option<Shell>,
    #[command(subcommand)]
    command: Option<Commands>,
}

#[derive(Subcommand, Debug, PartialEq)]
enum Commands {
    #[command(visible_alias = "hint")]
    ValueHint(ValueHintOpt),
............
}

fn print_completions<G: Generator>(generator: G, cmd: &mut Command) {
    generate(
        generator,
        cmd,
        cmd.get_name().to_string(),
        &mut io::stdout(),
    );
}

fn main() {
    let opt = Opt::parse();

    if let Some(generator) = opt.generator {
        let mut cmd = Opt::command();
        eprintln!("Generating completion file for {generator:?}...");
        print_completions(generator, &mut cmd);
    } else {
        println!("{opt:#?}");
    }
}

Steps to reproduce the bug with the above code

The reproducer is not really useful, it would be too big to put here. Technically completion for the big command (in my case it's 5Mb) when piped to the less (similarly to cargo r -p clap_complete --example completion-derive -- --generate bash | less just with the much bigger command) crashes when less aborts (i.e. quitting before reaching the end).

Actual Behaviour

failed to write completion file: Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }

Expected Behaviour

No panic

Additional Context

https://github.com/clap-rs/clap/blob/master/clap_complete/src/aot/shells/bash.rs#L78 (and for other generators as well) use "expect" causing application to crash when writing to the buffer fails. Instead result should be propagated to the caller so that there is a possibility to handle (or ignore) the error.
This is not visible with the existing examples, so I assume I face some sort of OS specific thresholds writing to the stdout.

Debug Output

clap_complete should not use expect when writing generated result into the buffer, but instead return the result

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-completionArea: completion generatorC-bugCategory: bugM-breaking-changeMeta: Implementing or merging this will introduce a breaking change.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions