coding-horror/basic-computer-games · error

Failed to read line

Error message

Failed to read line

What it means

A panic via .expect("Failed to read line") on io::stdin().read_line() in input_point() of the Battle Rust port, which reads an 'x,y' coordinate for a shot. read_line errors only on I/O-level failure (closed/EOF/broken stdin); malformed coordinate text (wrong number of fields, non-numeric) is handled by returning Err(()) up to the caller. The expect thus only fires when stdin itself cannot be read.

Source

Thrown at 09_Battle/rust/src/main.rs:172

}

impl fmt::Display for See {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for row in &self.data {
            write!(f, "\r\n")?;
            for cell in row {
                write!(f, "{:2} ", cell)?;
            }
        }
        write!(f, "\r\n")
    }
}

fn input_point() -> Result<Point, ()> {
    let mut input = String::new();
    io::stdin()
        .read_line(&mut input)
        .expect("Failed to read line");
    let point_str: Vec<&str> = input.trim().split(',').collect();

    if point_str.len() != 2 {
        return Err(());
    }

    let x = point_str[0].parse::<i8>().map_err(|_| ())?;
    let y = point_str[1].parse::<i8>().map_err(|_| ())?;

    Ok(Point(x, y))
}

fn get_next_target() -> Point {
    loop {
        print!("? ");
        let _ = io::stdout().flush();

        if let Ok(p) = input_point() {

View on GitHub (pinned to 5301155192)

Solutions

  1. Provide a coordinate line (e.g. '3,4') for every shot prompt in piped input.
  2. Run interactively.
  3. Replace .expect with handling that propagates an Err or exits cleanly on read failure.

Example fix

// before
io::stdin().read_line(&mut input).expect("Failed to read line");

// after
if io::stdin().read_line(&mut input).is_err() {
    return Err(());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Return Err(()) up to the caller instead of panicking
let n = io::stdin().read_line(&mut input);
if n.is_err() { return Err(()); }

Try / catch

// input_point already returns Result<Point, ()>; propagate read failure
let n = io::stdin().read_line(&mut input);
if n.is_err() { return Err(()); }

Prevention

When it happens

Trigger: stdin closed or exhausted before the player enters a coordinate; running the battle game with redirected input that ends; a broken pipe to stdin.

Common situations: Test fixtures that stop feeding input mid-game; piping `/dev/null`; an orchestration script that closes stdin after a fixed number of lines.

Related errors


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