вторник, 20 октября 2015 г.

Забавный баг

Недавно в одном разговоре вспомнилась забавная история, которую и захотелось рассказать.
История случилась несколько месяцев назад, когда мы в Intervale проводили интеграцию с Maxima Telecom в рамках проекта vmet.ro (он же wi-fi.ru).


В этом проекте Intervale предоставлял открытый rest-based api (для платежей, рекарринга и пр.), а Maxima Telecom являлся клиентом. В качестве транспорта использовался http-протокол. По api запросы должны были содержать специальный заголовок типа X-ABC-Custom (точное название заголовка на всякий случай не раскрываю); значение в этом заголовке было одним из факторов для выбора стратегии обработки (анонимный запрос, аутентифицированный пользователь, доверенный клиент и т.п.).

Коллегам из МТ было выслано детальное описание api в doc-документе, интеграция началась вполне успешно.

И вот однажды, при интеграционном тестировании какой-то части функционала на стороне Maxima Telecom стали получать ошибку аутентификации, и после некоторых попыток задали вопрос нам. Специалист по разворачиванию, администрированию и поддержке системы посмотрел логи, но найти причину не смог, и переадресовал реквест в разработку. И т. к. сразу не было понятно, в каком программном компоненте системы есть баг, то запрос ещё после некоторых блужданий попал ко мне.

Начал я опять-таки с логов. Исключений или сообщений об ошибках не было, значит, скорее всего, проблема возникала в штатном режиме (конечно, если ошибка не терялась где-то, но это маловероятно). Отказ (и его код, содержание) полностью соответствовал сценарию "анонимный пользователь пытается выполнить операцию, которая может быть выполнена только аутентифицированным пользователем" и порядку обработки этого сценария в системном security gate'е. Но по тем же логам видно, что на вход поступал запрос верного формата. Ок, проблемный компонент вроде был обнаружен.

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

Нашёл в логах пример подобной операции, которая проходила ранее (и параллельно с проблемных запросом) успешно, и принялся сравнивать с примером неуспешной операции. Сравнивать построчно, проверяя поля, заголовки, значения и пр. Вроде, всё совпадает, но одна строка в логе показалась чуть-чуть длиннее другой, и это насторожило. Путём постепенного отсекания было найдено расхождение:

X-ABC-Custom
и
XABCCustom

Разница заметна? Ну, только если приглядеться. И заключалась разница в длине тире: запрос с более коротким обрабатывался успешно, а с более длинным - нет. Причём разница была совсем небольшой, классические en dash и em dash из MS Word.

Наш компонент получал на вход запрос и проверял, а есть ли у него заголовок с коротким en dash (ожидаемый заголовок был задан в виде строки в java-коде); а в запросе оказывался заголовок с длинным em dash, проверка не проходила, запрос расценивался как анонимный.

Проверили - действительно, дело в этом.

Похоже на то, что при написании документации техническим писателем в его документе MS Word одно тире оказалось заменённым на другое (причём не везде, а только в некоторых примерах), и этого никто не заметил. А коллеги из Maxima Telecom использовали старую добрую практику copy + paste и тупо вставили значения из примеров, получив в одном случае успех, а в другом фэйл.

Кто ответственный за баг-то? ))

Комментариев нет:

Отправить комментарий