coding-horror/basic-computer-games · error

Failed to read line.

Error message

Failed to read line.

What it means

This panic is triggered by `.expect("Failed to read line.")` on `io::stdin().read_line()` inside the `read_line()` utility function in Nicomachus (line 68). This helper returns `String`, not `Result`, so callers have no way to detect or handle a read failure — the panic is the only failure mode.

Source

Thrown at 64_Nicomachus/rust/src/main.rs:68

        let input = read_line().trim().to_uppercase();
        let input = input.as_str();

        if input == "Y" || input == "YES" {
            return true;
        } else if input == "N" || input == "NO" {
            return false;
        } else {
            println!("Please input either (Y)es or (N)o.")
        }
    }
}

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

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

    input
}

View on GitHub (pinned to 5301155192)

Solutions

  1. Change `read_line()` to return `Option<String>`, mapping EOF and errors to `None`.
  2. Callers should check for `None` and exit the game gracefully.
  3. Provide complete input fixtures for non-interactive testing.

Example fix

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

// after
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: try-catch

Validate before calling

use std::io::IsTerminal;
if !io::stdin().is_terminal() {
    // Consider reading from a file or argument instead
}

Type guard

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

Try / catch

match io::stdin().read_line(&mut input) {
    Ok(0) | Err(_) => { println!("\nInput ended."); std::process::exit(0); }
    Ok(_) => { /* return input */ }
}

Prevention

When it happens

Trigger: Stdin returns `Err` or EOF. The function is called from every yes/no prompt in the game (the `yes_or_no` function at the top of the file uses it), so the crash can occur at any prompt. An empty line read (just Enter) returns `Ok` and does not trigger this panic.

Common situations: Non-interactive execution without stdin. Piped input file exhausted. Terminal closed mid-session. Running in a sandboxed environment with no TTY.

Related errors


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