{"record":{"id":"e651aabb833f73ed","repo":"coding-horror/basic-computer-games","slug":"failed-to-read-line-e651aa","errorCode":null,"errorMessage":"**Failed to read line**","messagePattern":"\\*\\*Failed to read line\\*\\*","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"51_Hurkle/rust/src/game.rs","lineNumber":41,"sourceCode":"            println!(\"SORRY, THAT'S {} GUESSES.\", self.tries);\n            println!(\"THE HURKLE IS AT {}, {}\", self.hurkle.0, self.hurkle.1);\n            return true;\n        }\n        self.tries += 1;\n        self.process_guess(self.get_guess())\n    }\n\n    fn get_guess(&self) -> Position {\n        let mut pos = (0, 0);\n\n        'guess: loop {\n            println!(\"GUESS # {}?\", self.tries);\n\n            let mut input = String::new();\n\n            io::stdin()\n                .read_line(&mut input)\n                .expect(\"**Failed to read line**\");\n\n            let input: Vec<&str> = input.trim().split(\",\").collect();\n\n            let mut is_y = false;\n            for a in input {\n                match a.parse::<u8>() {\n                    Ok(a) => {\n                        if a > 10 || a == 0 {\n                            println!(\"GUESS AXIS CANNOT BE ZERO OR LARGER THAN TEN!\");\n                            break;\n                        }\n                        if is_y {\n                            pos.1 = a;\n                            break 'guess;\n                        } else {\n                            pos.0 = a;\n                            is_y = true;\n                        }","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/51_Hurkle/rust/src/game.rs#L23-L59","documentation":"In 51_Hurkle, get_guess reads a comma-separated coordinate pair (e.g., '5,3') via io::stdin().read_line(&mut input).expect(\"**Failed to read line**\"). The input is split on commas and each axis is parsed as u8, with parse failures handled by printing an error and continuing the guess loop. The .expect() panics only on I/O-level failure.","triggerScenarios":"The game prompts 'GUESS # N?' and stdin returns Err or EOF. Malformed coordinates (wrong separator, out-of-range values) are handled by the validation logic, but missing input is not.","commonSituations":"Piped input that exhausts before all 5 guesses are made, pressing Ctrl+D at a coordinate prompt, or CI tests with insufficient input lines.","solutions":["Replace .expect() with .unwrap_or_default() so I/O failure yields an empty string, which the comma-split produces an empty vec that the validation loop handles by re-prompting","Use match to detect EOF and return a default Position to signal game-over","Break the guess loop on Err"],"exampleFix":"// before\nlet mut input = String::new();\nio::stdin()\n    .read_line(&mut input)\n    .expect(\"**Failed to read line**\");\n\nlet input: Vec<&str> = input.trim().split(\",\").collect();\n\n// after\nlet mut input = String::new();\nlet _ = io::stdin().read_line(&mut input);\n\nlet input: Vec<&str> = input.trim().split(\",\").collect();","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let mut input = String::new();\nlet _ = io::stdin().read_line(&mut input);\n// empty string splits into a vec with one empty element,\n// which fails parse::<u8>, triggering the retry loop","preventionTips":["For coordinate-parsing loops that already handle malformed input, let I/O failures produce empty strings that the validation catches","Use let _ = read_line(...) when the downstream parsing logic already loops on invalid input","Test coordinate-input games with truncated input to verify the validation loop handles EOF-induced empty strings"],"tags":["rust","stdin","read-line","panic","expect","io-error","eof","interactive","coordinate-input","cli"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}