Найди причину бага по трейсбэку и обстоятельствам. Начни с кадра, в котором упало, и с данных, которые в него пришли.
Трейс из ночного лога: [ТРЕЙС:
Traceback (most recent call last):
File "etl/daily_report.py", line 212, in build_daily
row["revenue"] = totals[row["shop_id"]]
KeyError: 4117
]
Что вокруг: [КОД: totals собирает agg_totals() одним запросом с group by shop_id за вчерашний день; build_daily идёт по всем магазинам из справочника shops]
Когда воспроизводится: [КОГДА: раз в несколько дней, только на ночном прогоне в 06:30; на локальной копии базы не повторяется ни разу]
Что уже пробовал: [ПРОБОВАЛ: обернул в try/except и подставил ноль — итоги отчёта разъехались с бухгалтерией]
Дай: что означает ошибка именно в этом месте, одним абзацем; до четырёх версий причины, самая сильная первой; к каждой версии — проверку в одну команду или один запрос, которую я выполню за минуту, и что я увижу, если версия верна; в конце — исправление по первой версии с объяснением, почему при нём остальные отпадают сами.
Отсечка. Падает раз в несколько дней, поэтому «добавь логирование и дождись следующего раза» — не ответ, это неделя ожидания: годятся только версии, проверяемые на уже собранных данных и на коде. Совет уровня «проверьте, существует ли ключ» тоже не годится — он верен для любого KeyError и не объясняет мой. Не переписывай функцию целиком и не проси прислать полный исходник: работай с тем, что дано, а чего не хватает, назови отдельной строкой как допущение.
Проверка. Каждая версия обязана объяснять оба факта разом: почему падает не каждый день и почему не воспроизводится локально. Версию, которая объясняет только один из двух, вычеркни сам и не показывай. Затем сверь список проверок с тем, что я уже пробовал: совпадений быть не должно.