В двух строках: код может работать для обычного названия кампании и ошибаться на символе «&». Я показываю нейросети не весь проект, а короткую функцию, вход с этим символом и то, что должно получиться. После объяснения проверяю исправление на нескольких вариантах.
В моей таблице было 17 ссылок для рассылки. Для кампании «Весна» генератор выдавал ожидаемую строку. Для «Весна&лето» ссылка выглядела почти так же, но часть после амперсанда могла читаться как новый параметр. Нейросеть для анализа кода здесь полезна не потому, что «знает Python», а потому, что ей можно показать точное расхождение между вводом и результатом. Мне понадобилось 7 минут ручной сверки, чтобы вообще заметить закономерность.
Как я нашла подозрительный символ
Я сначала смотрела на отчёт переходов. В названии одной кампании оставалась «Весна», а «лето» исчезало. Ссылка на глаз была целой: все буквы стояли на месте. Разница скрывалась в том, как строку читает программа после знака вопроса. Там «&» разделяет параметры. Если поставить его внутрь значения без кодирования, значение обрывается.
Вот сокращённая версия функции, из-за которой у меня появился вопрос:
~~~python
def add_campaign(base_url, campaign):
return base_url + "?utm_campaign=" + campaign
~~~
Она понятна даже человеку, который пишет код редко. Я сама сначала подумала: что тут ломать? Но склеивание строк не различает служебный символ и часть названия. При обычном слове ошибка незаметна. При «Весна&лето» она проявляется.
Я выписала рядом две строки из таблицы, не открывая весь проект. Для «Весна» значение метки после вопросительного знака было похоже на исходное название. Для «Весна&лето» я мысленно разделила строку по амперсанду и увидела две части. Этого хватило, чтобы уточнить вопрос к коду: почему часть названия превращается в границу параметров? Большой файл со всеми ссылками здесь только мешал бы. Сначала маленький вход, на котором видно отличие.
Если базовая ссылка уже содержит параметры, появляется второй случай: новый вопросительный знак вместо разделителя. А если у ссылки есть фрагмент после «#», дописывать метку в конец ещё опаснее: текст может оказаться внутри фрагмента, а не в запросе. Я поймала себя на том, что искала одну ошибку, а обнаружила семейство ошибок. Так устроены маленькие функции, которые обрабатывают внешние данные.