TeXitoi / structopt

Parse command line arguments by defining a struct.
Other
2.7k stars 149 forks source link

StackOverflow when parsing struct with custom fields #512

Closed lkadalski closed 2 years ago

lkadalski commented 2 years ago

Hi there, I check current issues but could not find matching one. I have some minimal example in playground When trying to run it with following: cargo run -- -h "h2" I have SO. thread 'main' has overflowed its stack fatal runtime error: stack overflow cargo run -- -h ...' terminated by signal SIGABRT (Abort) Using structopt = "0.3.25" Has anyone seen something similar? It happens with other substructs with custom FromStr implementation. I'm expecting nice error message instead of this.

TeXitoi commented 2 years ago

I can't reproduce

use core::str::FromStr;
use structopt::StructOpt;

#[derive(Debug)]
pub enum CliError {
    ValidationError(String),
}
#[derive(Debug, StructOpt, Clone)]
#[structopt(name = "TargetParameters")]
pub struct TargetParameters {
    /// HTTP Headers to use K: V
    #[structopt(short, long)]
    pub headers: Header,
}

#[derive(Debug, Clone)]
pub struct Header {
    pub name: String,
    pub value: String,
}

impl FromStr for Header {
    type Err = CliError;

    fn from_str(_header: &str) -> Result<Self, Self::Err> {
        Err(CliError::ValidationError("problem".to_string()))
    }
}
impl std::fmt::Display for CliError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        write!(f, "{:?}", self)
    }
}
fn main() {
    let _args = TargetParameters::from_args();
}
cargo run -- -h h2
   Compiling test-rs v0.1.0 (test-rs)
    Finished dev [unoptimized + debuginfo] target(s) in 0.46s
     Running `target/debug/test-rs -h h2`
error: Invalid value for '--headers <headers>': ValidationError("problem")

Maybe you implemented Display for CliError recursively? (write!(f, "{}", self) would be a recursive implementation, that obviously will stack overflow).

lkadalski commented 2 years ago

Yea, this is exactly what I did. write!(f, "{}", self)" calls Display recursively. My bad. Thanks @TeXitoi. Closing :+1: