fix(cli): surface typed parse errors for corrupt savegames (#206) #317
No reviewers
Labels
No labels
area/ci-release
area/cli
area/docs
area/dungeon
area/ftl
area/graphics
area/gui
area/music
area/saves
area/tooling
port/amiga
port/dos
port/fm-towns
port/mac
port/pc98
port/sega-cd
priority/high
priority/low
priority/medium
type/bug
type/chore
type/docs
type/feature
type/research
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
jqueuniet/dm2-tools!317
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/206-save-detect-typed-errors"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes the reopened half of #206.
Problem
Three of the four family probes (
try_parse_graphics,try_parse_ftl,try_open_resource_fork) areResult<Option<_>>, so a fingerprint match plus a parse failure surfaces the typed error.detect_savewas stillOption<_>and ran the fullSaveFile::parsewith.ok(), collapsing "recognised savegame, corrupt" into the sameNoneas "not a save at all". A truncated save fell through the whole probe chain and died with a generic message, even though the library had already computed the precise cause.Change
detect_save(crates/dm2-cli/src/commands/mod.rs) now returnsanyhow::Result<Option<_>>. Thelooks_like_*header predicates stay the family gate; once one matches,SaveFile::parse's error is propagated asmatched the {variant} savegame fingerprint but failed to parse: {e}. Both arms are covered — LE (dos-retail / dos-beta-v09) and BE (mac-retail).All five call sites
?the outerResultand keep their generic message for the genuine no-match case:info.rs,verify.rs,dump.rs,raw_extract.rs,save/mod.rs(load_save).dm2-convert's mirroreddetect_savealready propagated, so it needed no change.Before / after
The issue's exact repro:
dm2 verifyanddm2 save showgive the same diagnostic.Tests
mod.rsunit tests: fall-through on a non-save, typed error on a truncated one.tests/cli.rs:info_truncated_save_surfaces_typed_error,verify_truncated_save_surfaces_typed_error,info_non_save_still_falls_through_to_generic_message.tests/cli_save.rs:save_show_truncated_save_surfaces_typed_error.cargo test --workspace— 132 test binaries, 0 failures.cargo clippy -p dm2-cli --all-targetsclean for the changed files. CHANGELOG has an Unreleased/Fixed entry.https://claude.ai/code/session_013dMZoqpmA6U2BhTcNFbX15
`detect_save` ran the *full* `SaveFile::parse` and `.ok()`-ed its error away, collapsing "recognised family, corrupt" into the same `None` as "not a save at all". A truncated save therefore fell through the whole probe chain and died with a generic "could not identify" / "no known format matched" / "is not a recognised DM2 savegame", even though the library had already computed the precise cause. Make it `Result<Option<_>>` like its `try_parse_graphics` / `try_parse_ftl` / `try_open_resource_fork` siblings: the `looks_like_*` header fingerprint stays the family gate, and once it matches a parse failure is propagated instead of discarded. All five call sites (`info`, `verify`, `dump`, `raw-extract`, `save` via `load_save`) `?` the outer Result and keep their generic message for the genuine no-match case. $ head -c 5000 fixtures/dos-en/saves/sksave0.dat > truncated.dat $ dm2 info truncated.dat Error: truncated.dat Caused by: matched the dos-retail savegame fingerprint but failed to parse: sksave truncated: bitstream_offset 43485 >= file_len 5000 ... Covers both the LE (DOS retail / Beta) and BE (Mac retail) arms. Claude-Session: https://claude.ai/code/session_013dMZoqpmA6U2BhTcNFbX15