{"record":{"id":"aa3ecc76bcb24a6d","repo":"coding-horror/basic-computer-games","slug":"failed-to-read-the-line-aa3ecc","errorCode":null,"errorMessage":"Failed to read the line","messagePattern":"Failed to read the line","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"85_Synonym/rust/src/main.rs","lineNumber":35,"sourceCode":"    println!(\"LANGUAGE WHICH HAS THE SAME OR VERY NEARLY THE SAME MEANING.\");\n    println!(\"I CHOOSE A WORD -- YOU TYPE A SYNONYM.\");\n    println!(\"IF YOU CAN'T THINK OF A SYNONYM, TYPE THE WORD 'HELP'\");\n    println!(\"AND I WILL TELL YOU A SYNONYM.\\n\");\n}\n\nfn ask_question(mut this_question: Vec<&str>) {\n    let right_words = [\"RIGHT\", \"CORRECT\", \"FINE\", \"GOOD!\", \"CHECK\"];\n\n    // use the first one in the main question\n    let base_word = this_question.remove(0);\n\n    loop {\n        print!(\"     WHAT IS A SYNONYM OF {base_word}? \");\n        io::stdout().flush().unwrap();\n        let mut answer: String = String::new();\n        io::stdin()\n            .read_line(&mut answer)\n            .expect(\"Failed to read the line\");\n        let answer = answer.trim();\n        if answer == \"HELP\" {\n            // remove one random from the answers and show it\n            let random_index = thread_rng().gen_range(0..this_question.len());\n            println!(\n                \"**** A SYNONYM OF {base_word} IS {}.\",\n                this_question.remove(random_index)\n            );\n        } else if this_question.contains(&answer) {\n            println!(\"{}\", right_words.choose(&mut rand::thread_rng()).unwrap());\n            break;\n        }\n    }\n}\n\nfn main() {\n    const PAGE_WIDTH: usize = 64;\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/85_Synonym/rust/src/main.rs#L17-L53","documentation":"Inside the ask_question function for the Synonym game, read_line().expect(\"Failed to read the line\") reads the player's answer inside an infinite loop. The panic fires only on io::Error from read_line, not on EOF. On EOF (Ok(0)) the trimmed answer is empty, which is neither 'HELP' nor a match in this_question, so the loop repeats indefinitely — printing the prompt and reading EOF forever in a busy-spin.","triggerScenarios":"Piped input that runs out while the quiz loop is active. A dropped SSH or terminal session mid-quiz. A broken stdin pipe from a parent process that terminated early.","commonSituations":"Automated quiz testing with limited piped input. Running the synonym quiz under a script or CI pipeline. Terminal connection lost during interactive play.","solutions":["Match on read_line's Result; on Ok(0) break the loop or call process::exit(0) since the user has disconnected.","On Err(e), print the error and break the outer quiz loop gracefully.","Add a maximum-retry or abandon-on-EOF flag so the quiz terminates cleanly when input is exhausted.","For testing, pipe enough synonym answers to satisfy every question in the quiz."],"exampleFix":"// before\nio::stdin()\n    .read_line(&mut answer)\n    .expect(\"Failed to read the line\");\n\n// after\nmatch io::stdin().read_line(&mut answer) {\n    Ok(0) => { println!(\"\\nGoodbye!\"); return; }\n    Ok(_) => {}\n    Err(e) => { eprintln!(\"Input error: {e}\"); return; }\n}","handlingStrategy":"try-catch","validationCode":"// Break the quiz loop on EOF or error instead of spinning forever\nmatch io::stdin().read_line(&mut answer) {\n    Ok(0) => { println!(\"Goodbye!\"); return; }\n    Err(e) => { eprintln!(\"Input error: {e}\"); return; }\n    Ok(_) => { /* safe to trim and check answer */ }\n}","typeGuard":null,"tryCatchPattern":"// Inside the loop{...} of ask_question\nmatch io::stdin().read_line(&mut answer) {\n    Ok(n) if n > 0 => { /* have input, proceed with trim/check */ }\n    Ok(0) => break,  // EOF: exit quiz loop\n    Err(e) => {\n        eprintln!(\"{e}\");\n        break;\n    }\n}","preventionTips":["Always break infinite input loops on Ok(0) — sticky EOF causes busy-spins otherwise.","Test quiz programs with truncated piped input to verify they exit rather than hang.","Use return instead of break if the loop is inside a function with no cleanup needed.","Flush stdout before read_line (already done here) to ensure prompts appear in non-interactive mode."],"tags":["rust","io","stdin","panic","quiz-loop","infinite-spin"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}