Регистрация в сервисе часто начинается с ввода почты и ожидания кода подтверждения. Пользователь видит сообщение «Письмо отправлено» и закрывает вкладку, но код так и не приходит. В нашей практике такой сбой произошёл дважды за месяц: с 14 сентября по 1 октября и повторно 5 октября. API при этом возвращал 200, ошибок в логах не было. Ниже — разбор обоих случаев и выводы, которые помогут не наступить на те же грабли.

Первый инцидент: конфигурация, которая «сломалась» сама

В первом случае письма перестали уходить из-за изменения в конфигурации почтового шлюза. Мы обновляли настройки для другого проекта и случайно затронули общий параметр, отвечающий за аутентификацию. В результате запросы к SMTP-серверу отклонялись, но наша обёртка над отправкой не проверяла ответ сервера и возвращала успех. Пользователи не получали письма, а мы не видели проблемы, потому что мониторинг отслеживал только HTTP-код ответа API.

Типичная ошибка: считать, что код 200 от вашего API означает успешную доставку. На самом деле письмо могло застрять на любом этапе: от формирования до принятия почтовым сервером. В первом инциденте мы не проверяли ответ SMTP-сервера и не логировали ошибки на этом уровне. Исправление: добавили проверку кода ответа SMTP и стали логировать все ответы, кроме успешных. Также настроили алерт на рост доли ошибок отправки.

Второй инцидент: код, который не отправлял письма

5 октября проблема повторилась, но причина была другой. В коде обработчика регистрации использовалась функция отправки письма, которая в определённых условиях (например, при отсутствии шаблона для некоторых доменов) просто возвращала true, не выполняя отправку. Это было заложено как «временное решение» ещё на старте, но забыли убрать. В результате для части пользователей письма не отправлялись, а API отвечал успехом.

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

Что мы поменяли: диагностика и предотвращение

После двух инцидентов мы пересмотрели подход к мониторингу и тестированию. Вот конкретные шаги, которые стоит внедрить, если у вас есть отправка писем:

  • Проверяйте ответ почтового сервера. Не ограничивайтесь кодом 200 от вашего API. Убедитесь, что SMTP-сервер принял письмо, и логируйте его ответ. Если ответ не 250 (успех), считайте это ошибкой и обрабатывайте соответствующим образом.
  • Ведите метрики доставки. Считайте количество отправленных писем, количество успешных принятий сервером и количество ошибок. Настройте алерты при отклонении от нормы. Например, если доля ошибок превышает 1% за последние 5 минут — шлите уведомление.
  • Тестируйте отправку на разных доменах. В тестовом окружении прогоняйте сценарии с разными почтовыми провайдерами (Gmail, Яндекс, Mail.ru, корпоративные домены). Убедитесь, что для всех случаев письма реально уходят.
  • Уберите «заглушки» из продакшена. Если в коде есть функции, которые имитируют отправку, убедитесь, что они не используются в рабочей среде. Лучше, чтобы такие заглушки были явно отключены или заменены на реальную отправку.
  • Добавьте сквозной мониторинг. Используйте синтетические тесты: раз в несколько минут регистрируйте тестового пользователя с реальной почтой и проверяйте, что письмо приходит. Это поможет заметить проблему до жалоб.

Кроме того, мы пересмотрели обработку ошибок в API. Теперь, если отправка письма не удалась, пользователь видит не «Письмо отправлено», а сообщение с просьбой повторить попытку позже или связаться с поддержкой. Это снижает раздражение и даёт нам время на исправление.

Типичные ошибки, которые приводят к «тихим» сбоям

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

  • Игнорирование ответов внешних сервисов. Если вы вызываете внешний API (SMTP, сторонний сервис рассылок), всегда проверяйте его ответ. Не полагайтесь только на успешный HTTP-код.
  • Отсутствие логирования на уровне интеграций. Логируйте все запросы и ответы, особенно ошибки. Это поможет быстро найти причину сбоя.
  • Ручные изменения в конфигурации без проверки. Любое изменение в настройках почтовых шлюзов должно проходить через тестовую среду и проверку отправки.
  • Надежда на «авось пронесёт». Временные решения и заглушки имеют свойство оставаться в коде надолго. Регулярно проводите ревизию кода на предмет таких участков.

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