coding-horror/basic-computer-games · error

Failed to read input.

Error message

Failed to read input.

What it means

In 50_Horserace, the prompt function is a generic input handler that supports three modes (numeric, yes/no, or free text) via an Option<bool> parameter. It reads input via io::stdin().read_line(&mut input).expect("Failed to read input.") inside a loop. Parse/validation failures are handled gracefully by printing an error and continuing, but stdin I/O failures panic.

Source

Thrown at 50_Horserace/rust/src/util.rs:19

use std::io;

pub enum PromptResult {
    Normal(String),
    YesNo(bool),
    Numeric(i32),
}

pub fn prompt(is_numeric: Option<bool>, msg: &str) -> PromptResult {
    use PromptResult::*;

    println!("{msg}");

    loop {
        let mut input = String::new();

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

        if let Some(is_numeric) = is_numeric {
            let input = input.trim();

            if is_numeric {
                if let Ok(n) = input.parse::<i32>() {
                    return Numeric(n);
                }
                println!("PLEASE ENTER A VALID NUMBER!");
            } else {
                match input.to_uppercase().as_str() {
                    "YES" | "Y" => return YesNo(true),
                    "NO" | "N" => return YesNo(false),
                    _ => println!("PLEASE ENTER (Y)ES OR (N)O."),
                }
            }
        } else {
            return Normal(input);

View on GitHub (pinned to 5301155192)

Solutions

  1. Replace .expect() with .unwrap_or_default() so I/O failure yields an empty string that the existing validation catches and retries
  2. Use match on read_line to break the loop (and return a default PromptResult) on EOF
  3. Change prompt to return Option<PromptResult> so callers can detect I/O failure

Example fix

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

if let Some(is_numeric) = is_numeric {

// after
let _ = io::stdin().read_line(&mut input);

if let Some(is_numeric) = is_numeric {
Defensive patterns

Strategy: fallback

Try / catch

let _ = io::stdin().read_line(&mut input);
// empty string fails all validation checks (numeric parse,
// yes/no match), triggering the existing retry messages

Prevention

When it happens

Trigger: Any input prompt in the Horserace game (bet amount, horse selection, play again) when stdin is at EOF or the read fails. The loop would retry on bad input, but cannot recover from missing input.

Common situations: Running Horserace with piped input that exhausts mid-race, pressing Ctrl+D at a betting prompt, or CI tests with insufficient input lines.

Related errors


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