fix(state): log disk state files that fail to load instead of ignoring them
All Submissions:
- Have you followed the guidelines stated in CONTRIBUTING.md file?
- Have you checked to ensure there aren't any other open Pull Requests for the desired changed?
Type of change
- Bug fix (non-breaking change which fixes an issue)
Description
StateManagerDisk.load_state() caught every exception and returned None, so an existing state file that could not be loaded was handled like a missing one. get_state() started from a fresh state and the next write replaced the file, and nothing was logged.
This PR keeps the return value (still None, so the app keeps working from a fresh state, as the redis manager does on a mismatch) but makes the failure visible:
- File that cannot be read or unpickled (bad pickle bytes, truncated or empty file, a pickle referencing a missing module, IO errors): a
warningthat names the token and file path, with the traceback. - Stored schema no longer matches the state class (
StateSchemaMismatchErrorwith no chained cause): adebugrecord. This is an expected reset after editing a state class in dev, and a warning here would fire for every stale substate after each edit. - Missing file: unchanged, no log.
BaseState._deserialize also raises StateSchemaMismatchError for unpickling failures, but chains the original error, so a mismatch counts as an expected reset only when it has no chained cause.
I kept this to logging and didn't add a new exception or quarantine the file, because the issue doesn't settle the recovery behavior. If you'd prefer to raise, or to move the unreadable file aside before it gets overwritten, I can change it.
Closes #7167
Changes To Core Features:
- Have you added an explanation of what your changes do and why you'd like us to include them?
- Have you written new tests for your core changes, as applicable?
- Have you successfully ran tests with your changes locally?
Testing
New tests in tests/units/istate/manager/test_disk.py. All of them fail on main:
- missing file:
load_statereturnsNoneand logs nothing - unreadable file (
b"not-a-pickle"and an empty file for both a plainStateTokenand aBaseStateToken, plus a pickle that references a missing module): oneWARNINGthat names the token and path and carriesexc_info, andget_statestill returns a fresh state - stale schema (a valid pickle whose stored schema doesn't match): one
DEBUGrecord, no warning, andget_statereturns defaults
Commands run:
uv run pytest tests/units/istate/manager: 75 passeduv run pytest tests/units --cov --no-cov-on-fail --cov-report=: the only 3 failures also fail onmainin my environment (two dataeditor tests neednode, onereflex_benchHMR port test)uv run pre-commit run --files <changed files>(ruff format/check, codespell, pyright, ty): all pass
🤖 Opened with Superhuman, an open-source contribution agent.