{"record":{"id":"b339ed3081c70b19","repo":"coding-horror/basic-computer-games","slug":"failed-to-read-input-b339ed","errorCode":null,"errorMessage":"Failed to read input.","messagePattern":"Failed to read input\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"50_Horserace/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/50_Horserace/rust/src/util.rs#L1-L37","documentation":"In 50_Horserace, the prompt function is a generic input handler that supports three modes (numeric, yes/no, or free text) via an Option<bool> parameter. It reads input via io::stdin().read_line(&mut input).expect(\"Failed to read input.\") inside a loop. Parse/validation failures are handled gracefully by printing an error and continuing, but stdin I/O failures panic.","triggerScenarios":"Any input prompt in the Horserace game (bet amount, horse selection, play again) when stdin is at EOF or the read fails. The loop would retry on bad input, but cannot recover from missing input.","commonSituations":"Running Horserace with piped input that exhausts mid-race, pressing Ctrl+D at a betting prompt, or CI tests with insufficient input lines.","solutions":["Replace .expect() with .unwrap_or_default() so I/O failure yields an empty string that the existing validation catches and retries","Use match on read_line to break the loop (and return a default PromptResult) on EOF","Change prompt to return Option<PromptResult> so callers can detect I/O failure"],"exampleFix":"// before\nio::stdin()\n    .read_line(&mut input)\n    .expect(\"Failed to read input.\");\n\nif let Some(is_numeric) = is_numeric {\n\n// after\nlet _ = io::stdin().read_line(&mut input);\n\nif let Some(is_numeric) = is_numeric {","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let _ = io::stdin().read_line(&mut input);\n// empty string fails all validation checks (numeric parse,\n// yes/no match), triggering the existing retry messages","preventionTips":["For generic prompt functions with internal validation loops, ignore I/O errors so the validation logic handles empty strings","Centralize input reading in one helper and use let _ = to ensure all modes (numeric, yes/no, free text) degrade gracefully","Do not panic in utility functions that serve multiple call sites with different error-tolerance requirements"],"tags":["rust","stdin","read-line","panic","expect","io-error","eof","interactive","helper","cli"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}