Русский

Инструменты разработчика · JSON форматировщик и валидатор

Как валидатор JSON находит точную строку и столбец ошибки

· Как это работает

JSON проверка рабочий процесс разработчика

Каретка, расположенная под неожиданной клавишей в небольшом документе JSON
Оригинальная векторная иллюстрация ToolAcre

Браузеры сообщают об ошибках JSON.parse по-разному, а некоторые выдают только смещение символов. В этом посте объясняется, как валидатор превращает это в строку и столбец и почему позиция отмечает место остановки синтаксического анализа, а не место, где вы допустили ошибку.

Сообщение об ошибке, которое ничего вам не говорит: почему «Неожиданный токен в JSON в позиции 1432» бесполезен в 400-строчном файле

Такая ошибка, как «Неожиданный токен», разочаровывает в длинной конфигурации, поскольку она не предлагает места, которое можно было бы открыть в редакторе. JSON.parse — это авторитетный анализатор браузера, но его диагностический текст различается в зависимости от движков и версий JavaScript. ToolAcre не угадывает местоположение, сопоставляя нестабильную английскую строку ошибки. Если JSON.parse завершается неудачно, отдельный строгий сканер просматривает исходный текст, чтобы определить первый символ, который грамматика JSON не может принять.

Что на самом деле делает парсер JSON при чтении — описание токенизации и грамматики рекурсивного спуска, которая обрабатывает одно значение за раз.

JSON имеет шесть структурных символов — фигурные скобки, квадратные скобки, двоеточие и запятую — и значения, которые могут быть строками, числами, массивами, объектами, true, false или null. Сканер должен знать, находится ли она внутри строки в кавычках, прежде чем называть запятую разделителем: {"note":"A,B"} имеет одно значение, а не два. Он проходит через значение или член объекта и проверяет, что может следовать дальше. RFC 8259 определяет эту грамматику и, в отличие от объектных литералов JavaScript, не допускает комментариев или завершающих запятых.

От смещения символов до строки и столбца — подсчет новых строк до смещения ошибки и почему окончания CRLF и многобайтовые символы усложняют подсчет

Сканер обычно начинается со смещения, начинающегося с нуля, в исходной строке JavaScript. Чтобы это было полезно, посчитайте разрывы строк перед смещением и определите, насколько далеко находится сбой от последнего разрыва. CRLF следует рассматривать как окончание одной визуальной строки, а не двух строк; позиции в строках JavaScript учитывают UTF-16 единиц кода, а не UTF-8 байт на диске. Эмодзи, отличные от BMP, могут занимать две единицы кода в редакторе, который визуально отображает один глиф. Пользовательский интерфейс сообщает строку, столбец и отрывок, поэтому вы можете сверить курсор с вставленным файлом.

Ошибка не в том месте, где синтаксический анализ останавливается: в следующем ключе сообщается об отсутствующей запятой, а случайная кавычка может перенести ошибку на несколько строк вниз.

Первый невозможный токен часто находится после исходной ошибки. В объекте, если забыть запятую после true, кавычка, начинающая следующее свойство, недопустима: синтаксический анализатор ожидал запятую или закрывающую скобку. Незавершенная строка может привести к появлению ошибки при более позднем разрыве строки или конце ввода. Прочитайте назад от указанной точки, чтобы найти недостающий разделитель; не думайте, что символ под курсором необходимо удалить.

Рабочий пример: конфигурация с одной пропущенной запятой — сообщаемая позиция, окружающие токены и способ вернуться к реальной причине.

Попробуйте ввести буквальный трехстрочный документ {"name":"demo", за которым следует "enabled":true во второй строке и "port":8080} в третьей строке, без запятой после true. ToolAcre сообщает строку 3, столбец 1, смещение 31: после предыдущего свойства ожидается запятая или }, и под первой кавычкой «port» отображается курсор. Вставьте запятую в конце второй строки, затем подтвердите еще раз. Это диагностика первого синтаксического препятствия, а не суждение о том, что слово «порт» неверно.

Чем отличаются браузерные движки: V8, SpiderMonkey и JavaScriptCore по-разному описывают одну и ту же ошибку, поэтому помогает последовательный отчет в виде строк и столбцов.

V8, SpiderMonkey и JavaScriptCore использовали разные формулировки, а иногда и разные контекстные фрагменты для одной и той же ошибки JSON.parse. Сканер ToolAcre предоставляет свою собственную структурную причину и местоположение, когда собственный синтаксический анализатор отклоняет значение. Если сканер когда-либо не согласен с JSON.parse, инструмент возвращает ошибку механизма, а не создает позицию. Этот запасной вариант безопаснее, чем уверенно указывать на угаданный символ.

Чего это не касается — семантические проблемы, такие как неправильные типы, отсутствующие поля или нарушения схемы, которые валидатор синтаксиса никогда не отметит.

Синтаксически допустимый объект все равно может быть неправильным для вашего приложения: отсутствие обязательного поля, возраст, записанный в виде текста, два повторяющихся ключа или ссылка на несуществующий файл не являются автоматически недействительными JSON. RFC 8259 говорит, что имена членов должны быть уникальными для обеспечения совместимости, но простой анализ не обеспечивает соблюдение вашей схемы API. Проверьте синтаксис здесь и проверьте семантические ограничения в программе, которая использует документ.

Вывод: читайте позицию как «первый токен, который грамматика не смогла принять» — и как форматтер и валидатор JSON сообщает об этой строке и столбце, не загружая текст.

Рассматривайте указанную позицию как «первый токен, который эта грамматика не может принять». Вернитесь к причине, устраните одну проблему и повторите попытку. Средство форматирования и проверки JSON делает это локально, не загружая вставленную конфигурацию. Не вставляйте реальные производственные учетные данные на какой-либо общедоступный веб-сайт, если вместо этого оффлайн-редактор может диагностировать файл.