coding-horror/basic-computer-games · error

something went wrong getting secret from user

Error message

something went wrong getting secret from user

What it means

This panic is triggered by `.expect("something went wrong getting secret from user")` on `get_string_from_user_input("")` in the refactored Mastermind's human-codemaker mode (line 186). Same design defect as error 45: the helper returns a proper `Result`, but the caller panics on `Err`. This occurs when the human is supposed to enter a secret code for the computer to guess.

Source

Thrown at 60_Mastermind/rust/Mastermind_refactored_for_conventions/src/lib.rs:186

    println!("THE ACTUAL COMBINATION WAS: {}", secret.as_human_readible_chars());
    return Some(config.num_guesses); //max score gain per round
}

/// run a round with human as code-maker
/// returns the number of turns it takes the computer to guess the secret code
fn play_round_human_codemaker(config: &Config) -> Option<usize>{
    //DATA
    let mut rng = thread_rng();
    let mut all_possibilities = vec![true; config.total_possibilities];
    let _secret: Code;


    //get a secret code from user input
    println!("\nNOW I GUESS.  THINK OF A COMBINATION.\nHIT RETURN WHEN READY: ");
    // input loop
    _secret = loop {
        //get input
        let user_input = get_string_from_user_input("").expect("something went wrong getting secret from user");

        //parse input
        if let Ok(code) = Code::new_from_string(&user_input, config) {
            if code.code.len() == config.num_positions {break code;} //exit loop with code
            else {println!("CODE MUST HAVE {} POSITIONS", config.num_positions);continue;} //tell them to try again
        }
        println!("INVALID CODE.  TRY AGAIN"); //if unsuccessful, this is printed and the loop runs again
    };

    //round loop
    for computer_moves in 1..=config.num_guesses {
        let mut guess: Code = Code::new();

        //randomly generate a guess //770
        let mut guess_int = rng.gen_range(0..config.total_possibilities);
        // if possible, use it //780
        if all_possibilities[guess_int] {
            guess = Code::new_from_int(guess_int, &config); //create guess

View on GitHub (pinned to 5301155192)

Solutions

  1. Replace `.expect` with `match`/`?` that propagates the error or returns `None` to skip the round gracefully.
  2. Make `play_round_human_codemaker` return `Result<Option<usize>, Box<dyn Error>>` and use `?`.
  3. Ensure input fixtures include a valid secret code line before the codemaker phase reads it.

Example fix

// before
let user_input = get_string_from_user_input("")
    .expect("something went wrong getting secret from user");

// after
let user_input = match get_string_from_user_input("") {
    Ok(s) => s,
    Err(e) => { eprintln!("{}", e); return None; }
};
Defensive patterns

Strategy: try-catch

Validate before calling

// The helper returns Result; check it before using:
match get_string_from_user_input("") {
    Ok(s) => { /* parse as code */ }
    Err(e) => { eprintln!("{}", e); }
}

Type guard

// Result<String, Box<dyn Error>> is the type-level guarantee.
// Use match or ? to handle the Err variant.

Try / catch

match get_string_from_user_input("") {
    Ok(user_input) => { /* attempt Code::new_from_string */ }
    Err(e) => { eprintln!("{}", e); return None; }
}

Prevention

When it happens

Trigger: `get_string_from_user_input` returns `Err` because stdin's `read_line` failed. The input loop at line 188 is designed to retry on *invalid codes* (`Code::new_from_string` returning `Err`), but the `.expect` crashes on *I/O errors* before the parse even runs.

Common situations: Non-interactive execution of the codemaker phase. Stdin redirected from a file that ends before a valid secret code is provided. The refactored lib's `Result`-returning helper is undermined by the old `.expect` habit at call sites.

Related errors


AI-assisted analysis of coding-horror/basic-computer-games@5301155192 (2026-08-13). Data as JSON: /api/errors/4e5c31f702655cb7. Report an issue: GitHub.