Как пропускать некорректный JSON и продолжать обработку
Что проверяют
Различаете ли вы синтаксически битый JSON и корректный JSON с неверными данными и понимаете ли, где вообще можно «пропустить и продолжить». Следом спрашивают про большие файлы и про то, как не потерять пропущенные записи.
Как отвечать
Сначала уточните формат входа, от него зависит решение:
- JSON Lines (NDJSON): одна запись на строку, самый удобный случай. Поток читается построчно через
StreamReader.ReadLineAsync, каждая строка десериализуется в своёмtry/catch (JsonException). Сломанная строка не задевает соседние; - массив с ошибкой типа:
"Age": "abc"вместо числа, но синтаксически документ цел. Десериализуйте каждый элемент отдельно черезelement.Deserialize<Person>(), без лишнегоGetRawText(). Для файлов на гигабайты вместоJsonDocument.ParseберитеJsonSerializer.DeserializeAsyncEnumerable<JsonElement>(stream), он отдаёт элементы по одному; - синтаксически битый массив: незакрытая скобка в середине.
Utf8JsonReaderпосле ошибки дальше не читает, пропустить один элемент нельзя. Помогает только построчный формат.
Часть проблем снимают настройки JsonSerializerOptions: NumberHandling = JsonNumberHandling.AllowReadingFromString принимает числа строками, AllowTrailingCommas и ReadCommentHandling = JsonCommentHandling.Skip терпят лишние запятые и комментарии. В Newtonsoft.Json есть событие Error в JsonSerializerSettings, где args.ErrorContext.Handled = true пропускает проблемное место, в System.Text.Json прямого аналога нет.
Пропуск должен быть видимым. У JsonException есть Path, LineNumber и BytePositionInLine: пишите их в лог, а сырые записи складывайте в отдельный файл или очередь.
Где спотыкаются
Оборачивают в try/catch весь JsonDocument.Parse и думают, что так пропускаются отдельные записи. Падает весь документ.
Ловят Exception вместо JsonException и вместе с плохими данными глотают ошибки собственного кода.
Пропускают молча. Когда поставщик поменяет формат, отбрасываться начнёт каждая запись, а сервис будет спокойно отдавать пустоту. Нужен порог: если битых больше заданной доли, обработка останавливается с ошибкой.