{"record":{"id":"2249f7acf13b50f4","repo":"coding-horror/basic-computer-games","slug":"failed-to-read-input-2249f7","errorCode":null,"errorMessage":"**Failed to read input**","messagePattern":"\\*\\*Failed to read input\\*\\*","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"72_Queen/rust/src/util.rs","lineNumber":19,"sourceCode":"use std::io;\n\npub enum PromptResult {\n    Normal(String),\n    YesNo(bool),\n    Numeric(i32),\n}\n\npub fn prompt(is_numeric: Option<bool>, msg: &str) -> PromptResult {\n    use PromptResult::*;\n\n    println!(\"{msg}\");\n\n    loop {\n        let mut input = String::new();\n\n        io::stdin()\n            .read_line(&mut input)\n            .expect(\"**Failed to read input**\");\n\n        if let Some(is_numeric) = is_numeric {\n            let input = input.trim();\n\n            if is_numeric {\n                if let Ok(n) = input.parse::<i32>() {\n                    return Numeric(n);\n                }\n                println!(\"PLEASE ENTER A VALID NUMBER!\");\n            } else {\n                match input.to_uppercase().as_str() {\n                    \"YES\" | \"Y\" => return YesNo(true),\n                    \"NO\" | \"N\" => return YesNo(false),\n                    _ => println!(\"PLEASE ENTER (Y)ES OR (N)O.\"),\n                }\n            }\n        } else {\n            return Normal(input);","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/72_Queen/rust/src/util.rs#L1-L37","documentation":"This panic is triggered by `.expect(\"**Failed to read input**\")` on `io::stdin().read_line()` inside the `prompt()` function in Queen's `util.rs` (line 19). This function is the universal input handler, returning a `PromptResult` enum (`Numeric`, `YesNo`, etc.) for both numeric and text input. The `.expect` converts any I/O-level stdin failure into a crash before the enum-dispatch logic runs.","triggerScenarios":"`read_line` returns `Err` or EOF. The function's internal validation (`input.parse::<i32>()`, uppercase matching for YES/NO) happens *after* `read_line` succeeds, so invalid *content* never reaches the `.expect`. Only stream-level failures trigger it.","commonSituations":"Non-interactive execution. Piped input runs out mid-game. Terminal disconnection. The game is launched from a context (GUI app, IDE run config) without a wired-up stdin.","solutions":["Add a `Cancelled` or `Failed` variant to `PromptResult` and return it on `Ok(0)` or `Err` instead of panicking.","Change the function to return `Option<PromptResult>` so callers can detect EOF and exit.","For non-interactive use, provide complete input covering every `prompt()` call the game makes."],"exampleFix":"// before\nio::stdin().read_line(&mut input).expect(\"**Failed to read input**\");\n\n// after\nlet bytes = io::stdin().read_line(&mut input);\nmatch bytes {\n    Ok(0) | Err(_) => {\n        println!(\"\\nInput closed.\");\n        std::process::exit(0);\n    }\n    Ok(_) => {}\n}","handlingStrategy":"try-catch","validationCode":"use std::io::IsTerminal;\nif !io::stdin().is_terminal() {\n    eprintln!(\"Warning: non-interactive stdin.\");\n}","typeGuard":"pub fn prompt(is_numeric: Option<bool>, msg: &str) -> Option<PromptResult> {\n    // ...\n    let mut input = String::new();\n    match io::stdin().read_line(&mut input) {\n        Ok(0) | Err(_) => return None,\n        Ok(_) => { /* parse and return PromptResult */ }\n    }\n}","tryCatchPattern":"match io::stdin().read_line(&mut input) {\n    Ok(0) => { println!(\"\\nInput closed.\"); std::process::exit(0); }\n    Ok(_) => { /* dispatch to Numeric/YesNo */ }\n    Err(e) => { eprintln!(\"{}\", e); }\n}","preventionTips":["Add a Cancelled/Failed variant to the PromptResult enum for I/O errors.","Never .expect() on stdin in a function that returns an enum — add a failure variant instead.","Test with piped input that covers every prompt call in the game."],"tags":["rust","stdin","io","panic","expect","utility-function","cli-game"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}