coding-horror/basic-computer-games · error

Error loading stats data!

Error message

Error loading stats data!

What it means

This panic is triggered by `.expect("Error loading stats data!")` on `File::create("src/stats.txt")` inside `Stats::write()` in Splat (line 78). The message is misleading — `write()` is *saving* data, not loading it. The panic fires when `File::create` fails on the hardcoded relative path `src/stats.txt`, typically because the `src/` directory does not exist relative to the current working directory.

Source

Thrown at 81_Splat/rust/src/stats.rs:78

        let mut placement = all_jumps;

        for (i, altitude) in self.altitudes.iter().enumerate() {
            if a <= *altitude {
                placement = i + 1;
                break;
            }
        }

        utility::print_win(all_jumps, placement);

        self.altitudes.push(a);
        self.altitudes.sort_by(|a, b| a.partial_cmp(b).unwrap());

        self.write();
    }

    fn write(&self) {
        let mut file = File::create("src/stats.txt").expect("Error loading stats data!");

        let mut altitudes = String::new();

        for a in &self.altitudes {
            altitudes.push_str(format!("{},", a).as_str());
        }

        write!(&mut file, "{}", altitudes.trim()).expect("ERROR WRITING Stats FILE!");
    }
}

View on GitHub (pinned to 5301155192)

Solutions

  1. Use a proper data directory: `dirs::data_dir()` or a configurable path instead of the hardcoded `"src/stats.txt"`.
  2. Create the parent directory with `create_dir_all` before `File::create`.
  3. Replace `.expect` with error handling that logs the failure and degrades gracefully (skip the save, warn the user).
  4. Fix the misleading message to reflect the actual operation (writing, not loading).

Example fix

// before
fn write(&self) {
    let mut file = File::create("src/stats.txt").expect("Error loading stats data!");
    // ...
}

// after
fn write(&self) {
    let path = "src/stats.txt";
    let mut file = match File::create(path) {
        Ok(f) => f,
        Err(e) => {
            eprintln!("Warning: could not save stats: {}", e);
            return;
        }
    };
    // ...
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate path writability before the write() call
use std::path::Path;
let path = Path::new("src/stats.txt");
if let Some(parent) = path.parent() {
    if !parent.exists() {
        std::fs::create_dir_all(parent).ok();
    }
}

Type guard

fn can_write_stats() -> bool {
    let path = "src/stats.txt";
    let p = std::path::Path::new(path);
    p.parent().map(|d| d.exists() || std::fs::create_dir_all(d).is_ok())
        .unwrap_or(true)
}

Try / catch

fn write(&self) {
    let mut file = match File::create("src/stats.txt") {
        Ok(f) => f,
        Err(e) => {
            eprintln!("Warning: cannot save stats: {}", e);
            return;
        }
    };
    // ...
}

Prevention

When it happens

Trigger: The binary is run from a directory where `src/stats.txt` cannot be created (missing `src/` parent, permissions, read-only FS). Since `write()` is called from `add_altitude()` after every successful jump, this panic can occur mid-gameplay after stats are already in memory.

Common situations: Running the compiled binary outside the project root (the `src/` directory only exists during development). Deploying the binary without the source tree. The binary is installed system-wide but the hardcoded relative path points nowhere. This means stats saving works during development but breaks in production.

Related errors


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