{"record":{"id":"f0af008e69cb8bf8","repo":"coding-horror/basic-computer-games","slug":"error-reading-from-stdin","errorCode":null,"errorMessage":"Error reading from stdin","messagePattern":"Error reading from stdin","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"25_Chief/rust/src/main.rs","lineNumber":53,"sourceCode":"              X X\n             X X\n            XX\n           X\n          *\n\n#########################\n\nI HOPE YOU BELIEVE ME NOW, FOR YOUR SAKE!!\"\n    );\n}\n\nfn check_yes_answer() -> bool {\n    // reads from input and return true if it starts with Y or y\n\n    let mut answer: String = String::new();\n    io::stdin()\n        .read_line(&mut answer)\n        .expect(\"Error reading from stdin\");\n\n    answer.to_uppercase().starts_with('Y')\n}\n\nfn main() {\n    const PAGE_WIDTH: usize = 64;\n    print_center(\"CHIEF\".to_string(), PAGE_WIDTH);\n    print_center(\n        \"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\".to_string(),\n        PAGE_WIDTH,\n    );\n    println!(\"\\n\\n\\n\");\n\n    println!(\"I AM CHIEF NUMBERS FREEK, THE GREAT INDIAN MATH GOD.\");\n    println!(\"ARE YOU READY TO TAKE THE TEST YOU CALLED ME OUT FOR?\");\n\n    if !check_yes_answer() {\n        println!(\"SHUT UP, PALE FACE WITH WISE TONGUE.\");","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/25_Chief/rust/src/main.rs#L35-L71","documentation":"In 25_Chief, check_yes_answer reads a yes/no response via io::stdin().read_line(&mut answer).expect(\"Error reading from stdin\"). The .expect() panics if read_line returns Err, which occurs when stdin reaches EOF (input stream closed) or the stdin file descriptor is invalid. The function is called to check whether the user's answer starts with 'Y' across multiple points in the game's dialogue.","triggerScenarios":"Piping fewer input lines than the game expects (printf 'Y\\n' | cargo run when check_yes_answer is called twice), pressing Ctrl+D at the terminal to send EOF, or running in a non-interactive shell where stdin is /dev/null or closed.","commonSituations":"Automated test scripts that provide insufficient input, running the game in CI without allocating a PTY, piping from a here-doc with too few lines, or a user closing the terminal window mid-game.","solutions":["Replace .expect() with a match that returns false on Err, treating an I/O failure as a 'no' answer","Check whether read_line returned 0 bytes (EOF) and exit the game gracefully with a farewell message","Wrap the read in a helper that returns Option<String> and have callers decide how to handle None"],"exampleFix":"// before\nio::stdin()\n    .read_line(&mut answer)\n    .expect(\"Error reading from stdin\");\n\n// after\nif io::stdin().read_line(&mut answer).is_err() {\n    return false;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match io::stdin().read_line(&mut answer) {\n    Ok(0) => return false,  // EOF\n    Ok(_) => { /* process answer */ }\n    Err(_) => return false,\n}","preventionTips":["Detect Ok(0) from read_line as a distinct EOF signal and exit gracefully rather than treating it as an error","For yes/no helpers, default to 'no' on I/O failure so the game can exit cleanly","Never use .expect() on stdin reads in interactive programs — EOF is a normal user action (Ctrl+D), not a bug"],"tags":["rust","stdin","read-line","panic","expect","io-error","eof","interactive","cli"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}