{"record":{"id":"6ead1dcbcdca289a","repo":"coding-horror/basic-computer-games","slug":"failed-to-read-line-6ead1d","errorCode":null,"errorMessage":"Failed to read line","messagePattern":"Failed to read line","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"10_Blackjack/rust/src/main.rs","lineNumber":557,"sourceCode":"    THIS IS THE GAME OF 21. AS MANY AS 7 PLAYERS MAY PLAY THE\n    GAME. ON EACH DEAL, BETS WILL BE ASKED FOR, AND THE\n    PLAYERS' BETS SHOULD BE TYPED IN. THE CARDS WILL THEN BE\n    DEALT, AND EACH PLAYER IN TURN PLAYS HIS HAND. THE\n    FIRST RESPONSE SHOULD BE EITHER 'D', INDICATING THAT THE\n    PLAYER IS DOUBLING DOWN, 'S', INDICATING THAT HE IS\n    STANDING, 'H', INDICATING HE WANTS ANOTHER CARD, OR '/',\n    INDICATING THAT HE WANTS TO SPLIT HIS CARDS. AFTER THE\n    INITIAL RESPONSE, ALL FURTHER RESPONSES SHOULD BE 'S' OR\n    'H', UNLESS THE CARDS WERE SPLIT, IN WHICH CASE DOUBLING\n    DOWN IS AGAIN PERMITTED. IN ORDER TO COLLECT FOR\n    BLACKJACK, THE INITIAL RESPONSE SHOULD BE 'S'.\n    NUMBER OF PLAYERS\n\n    NOTE:'/' (splitting) is not currently implemented, and does nothing\n\n    PRESS ENTER TO CONTINUE\n    \");\n    io::stdin().read_line(&mut String::new()).expect(\"Failed to read line\");\n}\n\n/**\n * gets a usize integer from user input\n */\nfn get_number_from_user_input(prompt: &str, min:usize, max:usize) -> usize {\n    //input loop\n    return loop {\n        let mut raw_input = String::new(); // temporary variable for user input that can be parsed later\n\n        //print prompt\n        println!(\"{}\", prompt);\n        stdout().flush().expect(\"Failed to flush to stdout.\");\n        //read user input from standard input, and store it to raw_input\n        //raw_input.clear(); //clear input\n        io::stdin().read_line(&mut raw_input).expect( \"CANNOT READ INPUT!\");\n\n        //from input, try to read a number","sourceCodeStart":539,"sourceCodeEnd":575,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/10_Blackjack/rust/src/main.rs#L539-L575","documentation":"A panic via .expect(\"Failed to read line\") on io::stdin().read_line() in Blackjack's rules-display function that prints instructions then waits for ENTER to continue. read_line fails only on I/O-level errors (closed stdin, EOF, broken pipe). Because the read result is discarded into a fresh String, any read failure aborts the process at the 'PRESS ENTER TO CONTINUE' pause.","triggerScenarios":"The program prints the rules and waits for ENTER, but stdin is closed or at EOF (piped input exhausted, /dev/null, broken pipe); a non-interactive run that never supplies the ENTER.","commonSituations":"Piping pre-recorded input that omits the final ENTER; running headless with no TTY; CI that closes stdin after dealing setup lines.","solutions":["Include a trailing newline (ENTER) in piped input for the rules pause.","Run interactively.","Replace .expect with `let _ = io::stdin().read_line(&mut String::new());` to ignore failure at the continue prompt."],"exampleFix":"// before\nio::stdin().read_line(&mut String::new()).expect(\"Failed to read line\");\n\n// after\nlet _ = io::stdin().read_line(&mut String::new());","handlingStrategy":"fallback","validationCode":"// The read result is irrelevant; just ignore it so EOF won't abort.","typeGuard":null,"tryCatchPattern":"// Discard the read result for the continue prompt\nlet _ = io::stdin().read_line(&mut String::new());","preventionTips":["Never .expect a read whose value you discard (continue/exit prompts).","Include a trailing newline in piped input if the pause must return.","Gate the pause behind is_terminal() for non-interactive use."],"tags":["rust","stdin","io","panic","expect","continue-prompt"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}