Skip to content

Wrap corrupt cache reads in CacheCorruptError#62

Open
navidemad wants to merge 1 commit into
Gusto:mainfrom
navidemad:wrap-corrupt-cache-error
Open

Wrap corrupt cache reads in CacheCorruptError#62
navidemad wants to merge 1 commit into
Gusto:mainfrom
navidemad:wrap-corrupt-cache-error

Conversation

@navidemad
Copy link
Copy Markdown

Summary

FileCache#read leaks JSON::ParserError and KeyError directly to callers when the cache file on disk is malformed (truncated, hand-edited, partially written). The resulting error gives no hint that the file is FixtureKit's cache, what path it lives at, or how to recover.

Common scenarios where this surfaces:

  • A test run killed mid-write, leaving a half-flushed JSON file.
  • A user hand-edited a cache file to debug something and left it broken.
  • A partial filesystem failure or disk-full event during a write.

Fix

Wrap JSON::ParserError and KeyError raised inside FileCache#read in a new FixtureKit::CacheCorruptError whose message includes the cache path, the original error class and message, and a short remediation hint ("Delete it and re-run to regenerate.").

This is a strict superset of the previous behavior. A rescue on the new error class still catches malformed cache files, and StandardError catches everything as before.

Design notes

  • No retry, no auto-regeneration. Disk-vs-memory consistency bugs should surface loudly so the underlying cause (partial write, bad write code, hand edit) can be investigated. Auto-regenerating would paper over real bugs.
  • Errno::ENOENT is intentionally not wrapped. Missing-file semantics differ from corrupt-file semantics, and Cache#load already checks exists? first and raises CacheMissingError for the missing case.
  • The new error class lives next to the existing CacheMissingError in lib/fixture_kit.rb.

Related

Follow-up from review feedback on #61.

Test plan

  • bundle exec rspec spec/unit/file_cache_spec.rb — 11/11 pass (including 2 new specs for invalid JSON and missing keys)
  • bundle exec rspec (full suite) — 176/176 pass

FileCache#read leaks JSON::ParserError and KeyError to callers when
the cache file is malformed (truncated, hand-edited, partial write).
The original message gives no hint that the file is FixtureKit's
cache or that the fix is to delete and regenerate.

Wrap both error classes in a new FixtureKit::CacheCorruptError that
includes the cache path and the original error class/message, plus a
short note pointing at the remediation. This is a strict superset of
the previous behavior — a rescue on the new error class still catches
malformed cache files, and StandardError catches everything as before.

No retry, no auto-regeneration. Disk-vs-memory consistency bugs
should be loud, not silently papered over.
Copy link
Copy Markdown
Collaborator

@ngan ngan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, left a comment.

Comment on lines +36 to +39
rescue JSON::ParserError, KeyError => e
raise FixtureKit::CacheCorruptError,
"FixtureKit cache file at #{path} is corrupt or malformed (#{e.class}: #{e.message}). " \
"Delete it and re-run to regenerate."
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you localize these rescues so it's not rescuing errors across many statements doing very different things? Maybe move the JSON.parse(...) into its own method and do the rescue there. To DRY up the error message, you can bake it into the error class and you'd just pass in the error and the path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants