{"record":{"id":"4e5c31f702655cb7","repo":"coding-horror/basic-computer-games","slug":"something-went-wrong-getting-secret-from-user","errorCode":null,"errorMessage":"something went wrong getting secret from user","messagePattern":"something went wrong getting secret from user","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"60_Mastermind/rust/Mastermind_refactored_for_conventions/src/lib.rs","lineNumber":186,"sourceCode":"    println!(\"THE ACTUAL COMBINATION WAS: {}\", secret.as_human_readible_chars());\n    return Some(config.num_guesses); //max score gain per round\n}\n\n/// run a round with human as code-maker\n/// returns the number of turns it takes the computer to guess the secret code\nfn play_round_human_codemaker(config: &Config) -> Option<usize>{\n    //DATA\n    let mut rng = thread_rng();\n    let mut all_possibilities = vec![true; config.total_possibilities];\n    let _secret: Code;\n\n\n    //get a secret code from user input\n    println!(\"\\nNOW I GUESS.  THINK OF A COMBINATION.\\nHIT RETURN WHEN READY: \");\n    // input loop\n    _secret = loop {\n        //get input\n        let user_input = get_string_from_user_input(\"\").expect(\"something went wrong getting secret from user\");\n\n        //parse input\n        if let Ok(code) = Code::new_from_string(&user_input, config) {\n            if code.code.len() == config.num_positions {break code;} //exit loop with code\n            else {println!(\"CODE MUST HAVE {} POSITIONS\", config.num_positions);continue;} //tell them to try again\n        }\n        println!(\"INVALID CODE.  TRY AGAIN\"); //if unsuccessful, this is printed and the loop runs again\n    };\n\n    //round loop\n    for computer_moves in 1..=config.num_guesses {\n        let mut guess: Code = Code::new();\n\n        //randomly generate a guess //770\n        let mut guess_int = rng.gen_range(0..config.total_possibilities);\n        // if possible, use it //780\n        if all_possibilities[guess_int] {\n            guess = Code::new_from_int(guess_int, &config); //create guess","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/60_Mastermind/rust/Mastermind_refactored_for_conventions/src/lib.rs#L168-L204","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Replace `.expect` with `match`/`?` that propagates the error or returns `None` to skip the round gracefully.","Make `play_round_human_codemaker` return `Result<Option<usize>, Box<dyn Error>>` and use `?`.","Ensure input fixtures include a valid secret code line before the codemaker phase reads it."],"exampleFix":"// before\nlet user_input = get_string_from_user_input(\"\")\n    .expect(\"something went wrong getting secret from user\");\n\n// after\nlet user_input = match get_string_from_user_input(\"\") {\n    Ok(s) => s,\n    Err(e) => { eprintln!(\"{}\", e); return None; }\n};","handlingStrategy":"try-catch","validationCode":"// The helper returns Result; check it before using:\nmatch get_string_from_user_input(\"\") {\n    Ok(s) => { /* parse as code */ }\n    Err(e) => { eprintln!(\"{}\", e); }\n}","typeGuard":"// Result<String, Box<dyn Error>> is the type-level guarantee.\n// Use match or ? to handle the Err variant.","tryCatchPattern":"match get_string_from_user_input(\"\") {\n    Ok(user_input) => { /* attempt Code::new_from_string */ }\n    Err(e) => { eprintln!(\"{}\", e); return None; }\n}","preventionTips":["Never .expect() on a function that returns Result — it defeats the purpose of error propagation.","When refactoring, update all call sites to match the new Result-returning signature.","Use ? operator for clean error propagation up the call stack."],"tags":["rust","stdin","io","panic","expect","result-ignored","refactored","mastermind"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}