software-development
August 14

Гадание по скриншотам

Адская жара накрыла северную столицу, мешая думать и работать по основному профилю. Так что я временно переключился на менее затратные для мозга виды деятельности.

Ниже будет рассказ с картинками про интересную программерскую забаву — гадание по скриншотам:

Берется скриншот с программной ошибкой и разработчики пытаются объяснить причины, которые могли к ней привести.

Вы же не думали что только гусары умели развлекаться?

Кстати можете попробовать такое на интервью — процесс и полученные варианты ответов точно позабавят.

Начинаем это увлекательное мероприятие.

Скриншот первый: лимиты

Взято с некоего мобильного приложения для спортсменов:

С тех пор как нормальных программистов заменили «разработчики» а необходимость высшего технического образования для такой работы ныне вообще ставится под сомнение — появились последствия.

На скриншоте выше ярчайший пример допуска необразованного идиота к технической работе:

в формуле расчета аналитики по километрам не были заданы пограничные состояния и лимиты.

В какой-то момент случился технический сбой и приложение не смогло собрать данные с геотрекера, по которым строился график. И начало оперировать пустыми данными.

Возможное решение

Если вы разрабатываете подобное ПО — пожалуйста учитывайте возможные провалы в данных, физиологию человека и банальную логику:

очевидно что нельзя пробежать отрицательное количество километров, нельзя пробежать больше скажем 500 км за сутки и точно не стоит учитывать в расчете периоды с нулевым километражем.

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

Скриншот второй: неизвестная ошибка

Неизвестная ошибка, в данном случае в браузере Chrome, но такое может случиться где угодно:

Тут надо спросить всех любителей C/C++ и нативных приложений:

всю свою карьеру насмехались над Java и .NET, рассказывая окружающим что managed-окружение — «для неудачников»?

Поздравляю, ошибка выше специально для вашего морального унижения.

В это сложно поверить в 2025м году, но весь сложный путь с управляемой виртуальной машиной и байткодом, компилируемым на ходу был создан ради того чтобы подобных «безымянных ошибок» в программах не появлялось.

Хотя бы в прикладных и хотя-бы не каждый день.

И в Java/C# их действительно нет, за очень редкими исключениями. Зато есть в любом нативном приложении, на C/C++.

Возможное решение

Его нет (ахахахахаххаа), так что доставайте отладчик и вперед смотреть состояние регистров.

Таков путь.

Скриншот третий: шаблоны локализации

В этот раз сбой произошел у знаменитой платежной системы Paypal, что позволило хоть одним глазком взглянуть на «внутреннюю кухню» этой мировой компании:

У любого действия есть последствия, если вы реализовали веб-приложение в виде одного огромного скрипта (Angular),  вынеся строки локализации в подгружаемые ресурсы — у вас обязательно появятся такие ошибки.

Как это происходит?

Очень просто:

сам скрипт («bundle» в терминах Webpack) скачался и загрузился, а i18n ресурс уже нет.

Поскольку в самом приложении есть лишь ключевые слова вроде user-confirmation.user-understands именно их приложение и показывает.

Возможное решение

SPA-приложения не рассчитаны на функционирование при неполной загрузке, поэтому такого рода ошибки — вечный спутник любых Angular/React/Vue приложений.

Подход, когда управляющая логика располагается на клиентской стороне в Javascript-коде, который еще надо загрузить из сети, затем запустить и уже во время его выполнения подгрузить дополнительные ресурсы, вроде строк локализации всегда будет порождать подобные ошибки.

Так что какого-то общего решения тут нет, увы.

Скриншот четвертый: деление на ноль

Известный факт «делить на 0 нельзя» почему-то остался для современных разработчиков лишь в шутках и анекдотах, в реальных приложениях вот такое встречается постоянно:

В данном случае (видимо из-за нулей в позициях прайса) расчет общей стоимости дополнительных услуг оказался сломан и появилась такая страшная сумма, едва влезающая в активную область.

Возможное решение

Пожалуйста проверяйте что число на которое происходит деление обязательно больше нуля, если это не так — просто возвращайте 0 вместо рассчетов.

И все, это так просто.

Но повторюсь:

это очень частая ошибка, которая встречается повсеместно.

Скриншот пятый: реальная ошибка

Вы же наверняка видели знаменитый "Aw, snap!" в Хроме и подобные мусорные сообщения, которые скрывают от пользователя реальную причину ошибки?

Сейчас покажу почему так происходит:

Да, так выглядит реальная ошибка валидации в случае использования сложного паттерна.

Причем паттерн валидации адреса электронной почты почти настоящий и частично соответствует спецификации RFC для почтовых адресов.

Но если вы не имеете отношения к ИТ и разработке и увидите подобное темной ночью — как мининум огорчитесь, если не испугаетесь.

Возможное решение

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

Временами это примерно один раз на конкретную систему и в разделе «администрирование»

Достаточно было заменить это генерированное сообщение на что-то более осмысленное и человеческое, вроде «ошибка валидации email» и все, проблемы бы не было.

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

А в тех редких случаях где такое действительно надо — достаточно вставить ссылку на внешний документ с длинным текстом: пункты правил, статьи закона и так далее.

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

Скриншот шестой: JSON с особенностями

Да, такое тоже встречается на регулярной основе и не только в Индии:

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

Видимо малограмотный студент, которому поручили вставить ссылку на описание товара об этом не знал и попытался влепить пустой обработчик события — тот самый javascript:void(0); прямо в поле с названием товара в базе данных.

Результат на скриншоте выше.

Возможное решение

Тема обработки и отображения пользовательского контента на самом деле глобальна и всеобъемлюща.

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

Поэтому решение «в лоб» оставлю тут лишь для истории:

снять экранирование и пропустить текстовое значение поля JSON через eval()

Если вы не окончательно #бнутый, такое в реальном проекте никогда применять не станете.

Разумное решение это использование специальной верстки вроде Markdown для такого контента и разумеется полный запрет на вложенный javascript — в любом виде.