Skip to content

LoadOrCreate throws NullReferenceException instead of recovering when the settings file contains JSON null #295

Description

@matt-edmondson

What's wrong

In AppDataStorage/AppData.cs, AppData<T>.LoadOrCreate(...):

newAppData = JsonSerializer.Deserialize<T>(jsonString, AppData.JsonSerializerOptions)!;
newAppData.Subdirectory = subdirectory;

"null" is valid JSON. JsonSerializer.Deserialize<T>("null", ...) returns null without throwing JsonException for a reference type T. The ! only suppresses the compiler warning — at runtime newAppData really is null, and the very next line dereferences it, throwing NullReferenceException. Because no JsonException was thrown, the existing catch (JsonException) recovery path (fall back to the .bk backup, then create a fresh instance) never runs.

Why it matters / concrete failure scenario

Any settings file whose content is (or has been overwritten/truncated/corrupted to) the literal text null permanently breaks LoadOrCreate() for that app with an unhandled crash, instead of falling back to the backup or a fresh instance the way every other malformed-content case already does. This is a realistic corruption shape (e.g. a half-written file, or a writer that persists null for a missing root) that isn't covered by the existing tests — TestLoadOrCreateHandlesCorruptFile and TestLoadOrCreateRecoversFromCorruptBackup both use syntactically invalid JSON, which does throw JsonException and is handled correctly; the valid-but-null case is untested and unhandled.

Suggested fix

Treat a null deserialization result the same as a JsonException, e.g.:

newAppData = JsonSerializer.Deserialize<T>(jsonString, AppData.JsonSerializerOptions)
    ?? throw new JsonException("Deserialized settings file to null.");

inside the existing try block, so it flows into the current backup/fresh-instance recovery logic.

Acceptance criteria

  • A test where the settings file contains the literal text null results in LoadOrCreate() recovering (via backup or a fresh instance) instead of throwing.

Activity

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

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions