{"record":{"id":"1fdf62a4daea0360","repo":"coding-horror/basic-computer-games","slug":"error-writing-stats-file","errorCode":null,"errorMessage":"ERROR WRITING Stats FILE!","messagePattern":"ERROR WRITING Stats FILE!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"81_Splat/rust/src/stats.rs","lineNumber":86,"sourceCode":"\n        utility::print_win(all_jumps, placement);\n\n        self.altitudes.push(a);\n        self.altitudes.sort_by(|a, b| a.partial_cmp(b).unwrap());\n\n        self.write();\n    }\n\n    fn write(&self) {\n        let mut file = File::create(\"src/stats.txt\").expect(\"Error loading stats data!\");\n\n        let mut altitudes = String::new();\n\n        for a in &self.altitudes {\n            altitudes.push_str(format!(\"{},\", a).as_str());\n        }\n\n        write!(&mut file, \"{}\", altitudes.trim()).expect(\"ERROR WRITING Stats FILE!\");\n    }\n}\n","sourceCodeStart":68,"sourceCodeEnd":89,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/81_Splat/rust/src/stats.rs#L68-L89","documentation":"This panic is triggered by `.expect(\"ERROR WRITING Stats FILE!\")` on `write!(&mut file, ...)` inside `Stats::write()` in Splat (line 86). It fires when the `write!` macro fails to write the formatted altitude CSV string to the file handle. The file was just created by `File::create` on the preceding line, so a write failure here implies a low-level I/O problem after successful creation.","triggerScenarios":"Disk full, quota exceeded, NFS/network filesystem failure, or filesystem corruption between `File::create` and `write!`. The content being written is a comma-joined list of `f32` altitudes, so the data itself cannot cause a format error — only the I/O layer can.","commonSituations":"Disk full on the volume containing `src/`. Network filesystem timeout during the write. Filesystem quota exceeded. Running on a read-only filesystem where `File::create` appeared to succeed but writes fail (rare).","solutions":["Replace `.expect` with a `match`/`if let` that logs the error and warns the user that stats were not saved.","Write to a temporary file first and atomically rename on success, to avoid corrupting the existing stats file on partial write failure.","Check available disk space before writing in environments where this is a concern.","Handle `write!` error by retrying once before giving up."],"exampleFix":"// before\nwrite!(&mut file, \"{}\", altitudes.trim()).expect(\"ERROR WRITING Stats FILE!\");\n\n// after\nif let Err(e) = write!(&mut file, \"{}\", altitudes.trim()) {\n    eprintln!(\"Warning: could not write stats: {}\", e);\n}","handlingStrategy":"try-catch","validationCode":"// Check available disk space before writing (Unix)\nuse std::os::unix::fs::MetadataExt;\nif let Ok(meta) = std::fs::metadata(\"src/\") {\n    if meta.blocks() * meta.blksize() < 1024 {\n        eprintln!(\"Warning: low disk space.\");\n    }\n}","typeGuard":"// No type guard; write! returns io::Result.\n// Guard via match/if let on the Result.","tryCatchPattern":"if let Err(e) = write!(&mut file, \"{}\", altitudes.trim()) {\n    eprintln!(\"Warning: could not save stats: {}\", e);\n    return;\n}","preventionTips":["Write to a temp file and atomically rename on success to avoid corrupting existing data.","Handle write! errors with logging and graceful degradation.","Monitor disk space in long-running processes that write frequently."],"tags":["rust","file-io","panic","expect","write","disk-full","splat","stats-persistence"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}