При разработке механизмов рассылки отчетов или уведомлений часто возникает ситуация: интерактивный вызов процедуры отправки из формы или обработки отрабатывает без нареканий, но при переносе этого же кода в регламентное или фоновое задание отправка завершается ошибкой. При этом в блоке исключения метод ОписаниеОшибки() может возвращать пустую строку, а метод Сообщить() в фоновых процессах не выводит сообщение на экран пользователя.
Разберем детально, почему возникает такая разница в поведении, как правильно диагностировать ошибки в фоновых процессах и как корректно настроить параметры профиля электронной почты.
Проанализируем основные системные и программные факторы, вызывающие ошибку в фоновом режиме:
rphost) под учетной записью службы (например, USR1CV8). Корпоративный почтовый сервер может разрешать отправку без строгой авторизации для клиентской сети, но блокировать серверный сегмент с ошибкой 454 Relay access denied.ИнтернетПочтовоеСообщение явно не задано свойство Отправитель или оно не совпадает с логином аутентификации из ИнтернетПочтовыйПрофиль.ПользовательSMTP, почтовые серверы расценивают попытку отправки как спам-релей и сбрасывают соединение.ИспользоватьSSLSMTP или ИспользованиеЗащищенногоСоединенияSMTP) и способа аутентификации (СпособSMTPАутентификации.ПоУмолчанию).Сообщить() в фоновых задачах не отображается в интерфейсе. Если не записывать события в системный журнал, разработчик видит лишь факт падения задания без контекста.Чтобы выяснить точную причину ошибки в фоновом задании, необходимо получать развернутую структуру исключения и фиксировать ее в журнале регистрации. Посмотрим на правильную реализацию блока перехвата ошибок:
Попытка
Почта = Новый ИнтернетПочта;
Почта.Подключиться(Профиль);
Почта.Послать(Письмо);
Почта.Отключиться();
Исключение
ИнфоОбОшибке = ИнформацияОбОшибке();
ПодробныйТекст = ПодробноеПредставлениеОшибки(ИнфоОбОшибке);
// Записываем ошибку в системный журнал регистрации
ЗаписьЖурналаРегистрации(
"ОтправкаПочты",
УровеньЖурналаРегистрации.Ошибка,
,
,
ПодробныйТекст
);
// Обязательно освобождаем сетевой ресурс при сбое
Попытка
Почта.Отключиться();
Исключение
// Игнорируем ошибку отключения, если соединение не было открыто
КонецПопытки;
КонецПопытки;
Рассмотрим рабочий программный код для отправки почты через объект ИнтернетПочта, оптимизированный для стабильной работы как в интерактивном режиме, так и внутри регламентных и фоновых заданий:
Процедура ОтправитьПочтуСервер(АдресПолучателя, ТемаПисьма, ТекстПисьма) Экспорт
// 1. Инициализируем и заполняем параметры профиля подключения
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераSMTP = "smtp.yandex.ru";
Профиль.ПортSMTP = 465;
Профиль.ПользовательSMTP = "robot@company.ru";
Профиль.ПарольSMTP = "СекретныйПарольПриложения";
Профиль.ВремяОжидания = 30;
// Явно указываем параметры безопасности и аутентификации
Профиль.АутентификацияSMTP = СпособSMTPАутентификации.ПоУмолчанию;
Профиль.ИспользоватьSSLSMTP = Истина;
// 2. Формируем почтовое сообщение
Письмо = Новый ИнтернетПочтовоеСообщение;
// Критически важно: адрес отправителя должен совпадать с логином SMTP
Письмо.Отправитель = "robot@company.ru";
Письмо.ИмяОтправителя = "Служба уведомлений 1С";
Письмо.Тема = ТемаПисьма;
Письмо.Получатели.Добавить(АдресПолучателя);
// Добавляем текст письма
ТекстСообщения = Письмо.Тексты.Добавить(ТекстПисьма);
ТекстСообщения.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;
// 3. Выполняем подключение и отправку
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(Профиль);
Почта.Послать(Письмо);
Почта.Отключиться();
Исключение
ТекстИсключения = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(
"ОтправкаПочты",
УровеньЖурналаРегистрации.Ошибка,
,
,
ТекстИсключения
);
Попытка
Почта.Отключиться();
Исключение
КонецПопытки;
ВызватьИсключение "Ошибка отправки письма: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Отправитель: Убедитесь, что объекту ИнтернетПочтовоеСообщение явно присвоен корректный адрес электронной почты.25, 465 или 587.Профиль.АутентификацияSMTP = СпособSMTPАутентификации.ПоУмолчанию.