Repository navigation
Recover from a saved value a semantic type rejects, and retry Get() after a failed load [patch] - #344
Merged
matt-edmondson merged 2 commits intoOct 9, 2026
Conversation
…fter a failed load [patch] A value that is well-formed JSON but fails a semantic type's validation surfaced as ArgumentException, which LoadOrCreate did not catch, so it escaped and the file was left to fail again on every launch. Route ArgumentException, FormatException and NotSupportedException from deserialization to the same archive-and-retry path as JsonException. InternalState was a Lazy<T> in ExecutionAndPublication mode, which caches the exception, so one failed load made every Get() throw for the rest of the process. It is now PublicationOnly, so the next Get() tries again. Fixes #315 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J9ABDLXQgwyGEboxA8DpmQ
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J9ABDLXQgwyGEboxA8DpmQ
|
matt-edmondson
deleted the
claude/appdatastorage-315-semantic-rejection
branch
October 9, 2026 08:00
This was referenced Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #315
What changed
LoadOrCreatehandles more failures. It now sendsArgumentException,FormatExceptionandNotSupportedExceptionthrown during deserialization to the existing archive-and-retry path, the same pathJsonExceptionalready took. A value can be well-formed JSON and still be rejected by a semantic type: a Windows path read on Linux, validation tightened in an app update, or a hand edit. Before, the converter'sArgumentExceptionescaped and the file stayed on disk, so the app crashed on every launch. Now the file is archived as<file>.corrupt.<timestamp>, the archiving from A settings file that fails to deserialize is deleted outright and replaced with defaults, with no backup left to recover from #314 / Archive a settings file that fails to deserialize instead of deleting it [patch] #337, and defaults are loaded.InternalStateis nowLazyThreadSafetyMode.PublicationOnly. The default mode cached the first exception, so after one failed load everyGet(),QueueSave()andSaveIfRequired()rethrew it for the rest of the process. Now the nextGet()tries the load again.LoadOrCreateholds the lock, so racing first calls still load one at a time and only one result is published.Tests
TestLoadOrCreateRecoversFromAValueASemanticTypeRejects: a settings file whoseAbsoluteDirectoryPathvalue isnot/absolute. A relative path is rejected on every OS, unlike the issue'sC:/…fixture, which is valid on Windows.LoadOrCreatemust return defaults and archive the original content.TestGetRetriesAfterAFailedLoadInsteadOfRethrowingIt: a type whose constructor throws once. The secondGet()must succeed.AppData.cschange is reverted.🤖 Generated with Claude Code
https://claude.ai/code/session_01J9ABDLXQgwyGEboxA8DpmQ
Generated by Claude Code