coding-horror/basic-computer-games · error

Error reading line.

Error message

Error reading line.

What it means

In 29_Craps, the util module exposes a read_line() helper that wraps io::stdin().read_line(&mut input).expect("Error reading line."). Every input in the game flows through this function — both read_numeric (for numeric bets) and prompt (for yes/no decisions). The .expect() panics on any stdin I/O failure, crashing the entire game.

Source

Thrown at 29_Craps/rust/src/util.rs:13

use std::io;

pub enum Response {
    Yes,
    No,
}

pub fn read_line() -> String {
    let mut input = String::new();

    io::stdin()
        .read_line(&mut input)
        .expect("Error reading line.");

    input
}

pub fn read_numeric(message: &str) -> usize {
    loop {
        println!("{}", message);

        let mut ok = true;

        let input = read_line();

        for c in input.trim().chars() {
            if !c.is_numeric() {
                println!("You can only enter a number!");
                ok = false;
                break;
            }

View on GitHub (pinned to 5301155192)

Solutions

  1. Change read_line to return Result<String, io::Error> and use ? in callers, letting the game's main function decide whether to exit or retry
  2. Return Option<String> from read_line (None on EOF/error) and have callers loop or exit on None
  3. Add a loop that retries the read on transient errors but exits on EOF

Example fix

// before
pub fn read_line() -> String {
    let mut input = String::new();
    io::stdin()
        .read_line(&mut input)
        .expect("Error reading line.");
    input
}

// after
pub fn read_line() -> Option<String> {
    let mut input = String::new();
    match io::stdin().read_line(&mut input) {
        Ok(0) | Err(_) => None,
        Ok(_) => Some(input),
    }
}
Defensive patterns

Strategy: fallback

Try / catch

pub fn read_line() -> Option<String> {
    let mut input = String::new();
    match io::stdin().read_line(&mut input) {
        Ok(0) | Err(_) => None,
        Ok(_) => Some(input),
    }
}

Prevention

When it happens

Trigger: Any point in the Craps game where the player must enter input (bet amount, roll-again prompt) and stdin is at EOF or the read syscall fails. Since all input routes through this helper, a single piped-input exhaustion crashes the game.

Common situations: Running Craps in CI with piped input that runs out mid-game, a user pressing Ctrl+D during a betting round, or a test harness that closes stdin after the first prompt.

Related errors


AI-assisted analysis of coding-horror/basic-computer-games@5301155192 (2026-08-13). Data as JSON: /api/errors/088cae4651e695b1. Report an issue: GitHub.