{"record":{"id":"8f44284788602d5d","repo":"coding-horror/basic-computer-games","slug":"failed-to-read-line-8f4428","errorCode":null,"errorMessage":"Failed to read line.","messagePattern":"Failed to read line\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"96_Word/rust/src/word_game.rs","lineNumber":52,"sourceCode":"        self.guesses += 1;\n\n        println!(\"\\n\\nGuess a five letter word?\");\n\n        let mut game_over = false;\n\n        if WordGame::<'_>::read_guess(self) {\n            game_over = WordGame::<'_>::process_guess(self);\n        }\n\n        game_over\n    }\n\n    fn read_guess(&mut self) -> bool {\n        let mut guess = String::new();\n\n        io::stdin()\n            .read_line(&mut guess)\n            .expect(\"Failed to read line.\");\n\n        let invalid_input = |message: &str| {\n            println!(\"\\n{} Guess again.\", message);\n            return false;\n        };\n\n        let guess = guess.trim();\n\n        for c in guess.chars() {\n            if c.is_numeric() {\n                return invalid_input(\"Your guess cannot include numbers.\");\n            }\n            if !c.is_ascii_alphabetic() {\n                return invalid_input(\"Your guess must only include ASCII characters.\");\n            }\n        }\n\n        if guess.len() != 5 {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/96_Word/rust/src/word_game.rs#L34-L70","documentation":"The read_guess method on the WordGame struct calls read_line().expect(\"Failed to read line.\") to read the player's letter guess. The panic fires on io::Error from read_line. On EOF (Ok(0)) the trimmed guess is empty; the validation loop iterates zero characters, so no invalid_input closure fires — the method likely returns false (no valid guess submitted), and the caller skips processing the guess, potentially looping forever depending on the calling game loop structure.","triggerScenarios":"stdin pipe closed during gameplay. A terminal connection lost mid-guess. Non-interactive execution where stdin exhausts before the game ends.","commonSituations":"Piped input for automated Word game testing that runs out of guesses mid-game. Docker or CI without interactive stdin. Script that provides partial input.","solutions":["Match on read_line; on Ok(0) return false and signal the caller to end the game.","On Err(e), eprintln the error and return false so the caller can detect the failure.","Add an explicit empty-input check after trimming: if guess.is_empty(), return false or break the game loop.","For testing, ensure piped input covers every guess the game will request."],"exampleFix":"// before\nio::stdin()\n    .read_line(&mut guess)\n    .expect(\"Failed to read line.\");\n\n// after\nmatch io::stdin().read_line(&mut guess) {\n    Ok(0) => return false, // EOF: no guess\n    Ok(_) => {}\n    Err(e) => {\n        eprintln!(\"Input error: {e}\");\n        return false;\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Return false on EOF/error so the caller skips guess processing\nfn read_guess(&mut self) -> bool {\n    let mut guess = String::new();\n    match io::stdin().read_line(&mut guess) {\n        Ok(0) => return false,  // EOF: no guess\n        Err(e) => {\n            eprintln!(\"Input error: {e}\");\n            return false;\n        }\n        Ok(_) => { /* proceed with validation */ }\n    }\n    // ... rest of validation ...\n}","typeGuard":null,"tryCatchPattern":"// In read_guess method — match replaces expect\nmatch io::stdin().read_line(&mut guess) {\n    Ok(n) if n > 0 => { /* have input, validate characters */ }\n    Ok(0) => return false,   // EOF: signal no valid guess\n    Err(e) => {\n        eprintln!(\"{e}\");\n        return false;\n    }\n}","preventionTips":["Return false from read_guess on EOF so the caller's game loop can detect disconnection.","Check for empty guess after trim — an empty string should be rejected, not silently accepted.","Ensure the calling play loop checks the return of read_guess AND handles repeated false returns (potential infinite loop).","Test with piped input that exhausts mid-game to verify graceful termination."],"tags":["rust","io","stdin","panic","guess-reader","word-game","struct-method"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}