{"record":{"id":"24bb3edc25bdddd2","repo":"coding-horror/basic-computer-games","slug":"cannot-read-input-24bb3e","errorCode":null,"errorMessage":"CANNOT READ INPUT!","messagePattern":"CANNOT READ INPUT!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"10_Blackjack/rust/src/main.rs","lineNumber":573,"sourceCode":"    PRESS ENTER TO CONTINUE\n    \");\n    io::stdin().read_line(&mut String::new()).expect(\"Failed to read line\");\n}\n\n/**\n * gets a usize integer from user input\n */\nfn get_number_from_user_input(prompt: &str, min:usize, max:usize) -> usize {\n    //input loop\n    return loop {\n        let mut raw_input = String::new(); // temporary variable for user input that can be parsed later\n\n        //print prompt\n        println!(\"{}\", prompt);\n        stdout().flush().expect(\"Failed to flush to stdout.\");\n        //read user input from standard input, and store it to raw_input\n        //raw_input.clear(); //clear input\n        io::stdin().read_line(&mut raw_input).expect( \"CANNOT READ INPUT!\");\n\n        //from input, try to read a number\n        match raw_input.trim().parse::<usize>() {\n            Ok(i) => {\n                if i < min || i > max { //input out of desired range\n                    println!(\"INPUT OUT OF VALID RANGE.  TRY AGAIN.  {}-{}\",min,max);\n                    continue; // run the loop again\n                }\n                else {\n                    break i;// this escapes the loop, returning i\n                }\n            },\n            Err(e) => {\n                println!(\"INVALID INPUT.  TRY AGAIN.  {}\", e.to_string().to_uppercase());\n                continue; // run the loop again\n            }\n        };\n    };","sourceCodeStart":555,"sourceCodeEnd":591,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/10_Blackjack/rust/src/main.rs#L555-L591","documentation":"A panic via .expect(\"CANNOT READ INPUT!\") on io::stdin().read_line() inside get_number_from_user_input() of the Blackjack Rust port, used to read numeric bets/choices within a min..max range. read_line returns Err only on I/O-level failure (closed stdin, EOF, broken pipe); out-of-range or non-numeric input is handled by the parse branch with a re-prompt. The expect aborts on any read error.","triggerScenarios":"stdin closed or exhausted before a numeric prompt is answered; redirected input that ends mid-game; broken pipe to stdin.","commonSituations":"Test/CI runs whose input fixture runs out of lines; piping /dev/null; a feeder script that closes stdin after a fixed count.","solutions":["Provide a numeric line within the valid range for every prompt in piped input.","Run interactively so stdin remains open.","Swap .expect for `match` that exits or returns a default on read error."],"exampleFix":"// before\nio::stdin().read_line(&mut raw_input).expect(\"CANNOT READ INPUT!\");\n\n// after\nif io::stdin().read_line(&mut raw_input).is_err() {\n    println!(\"\\nInput unavailable. Exiting.\");\n    std::process::exit(1);\n}","handlingStrategy":"try-catch","validationCode":"// Ensure stdin is open before prompting; provide one in-range numeric line per call when piping.","typeGuard":null,"tryCatchPattern":"// Replace .expect with a match\nmatch io::stdin().read_line(&mut raw_input) {\n    Ok(_) => { /* parse usize in [min,max] */ }\n    Err(_) | Ok(0) => { println!(\"Input closed. Exiting.\"); std::process::exit(1); }\n}","preventionTips":["Match read_line's Result instead of .expect for interactive input.","Size piped input to cover every prompt with in-range values.","Treat Ok(0) as EOF and exit cleanly."],"tags":["rust","stdin","io","panic","expect"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}