Как правильно реализовать асинхронную отправку транспортных ВСД в ВетИС и обработать ошибки 504 и APLM12

Программист 1С v8.3 (Управляемые формы) Промышленность, строительство и АПК
← На главную

Переход на асинхронную модель взаимодействия с системой «Меркурий» (ВетИС.API) является необходимым шагом при больших объемах отгрузок. Однако разработчики часто сталкиваются с непредсказуемым поведением шлюза: зависанием заявок, дублями документов и непонятными системными ошибками. В этой статье мы подробно разберем, как построить надежный механизм обмена, проанализируем причины возникновения ошибок 504 Gateway Timeout и APLM12, а также выработаем оптимальную стратегию обработки ответов.

Природа ошибки 504 и почему нельзя повторять запрос сразу

Рассмотрим ситуацию: ваша система отправляет запрос на оформление транспортного ВСД и получает в ответ HTTP-статус 504 Gateway Timeout. Ошибка 504 означает, что прокси-сервер (шлюз ВетИС) не дождался ответа от внутреннего прикладного сервера системы за отведенное время.

Важный нюанс: статус 504 не является подтверждением того, что запрос отклонен. В архитектуре ВетИС это «неопределенное состояние». Если запрос успел дойти до прикладного сервера и попасть в очередь, он будет обработан, даже если клиент получил тайм-аут. Если в этот момент отправить повторный запрос с новым локальным идентификатором, система создаст второй (дублирующий) ВСД.

Проанализируем правильный алгоритм действий при получении 504 ошибки:

  1. Не паниковать и не удалять тикет. Сохраните локальный идентификатор заявки applicationId.
  2. Выполнить проверку. Вместо повторной отправки данных, необходимо вызвать метод getServiceDecision или getProcessChanges, передав туда тот же applicationId.
  3. Ожидать результат. Если в ответ на проверку система возвращает информацию о созданном тикете или готовом результате, значит, первая отправка прошла успешно.

Разбор системной ошибки APLM12

Ошибка с кодом APLM12 часто ставит разработчиков в тупик, так как описание в документации обычно сводится к фразе «Системная ошибка». На практике она возникает в следующих случаях:

Выясним причину появления этой ошибки в вашем коде. Если вы используете многопоточную отправку, попробуйте временно перевести систему в однопоточный режим по конкретной площадке (Enterprise Service GUID). Как показывает опыт, ВетИС стабильнее работает, когда запросы от одного отправителя идут последовательно, а не параллельно.

Стратегия работы со статусом IN_PROCESS

Длительное нахождение тикета в статусе IN_PROCESS — это нормальная ситуация для периодов пиковой нагрузки (утренние часы пик). Посмотрим на пример эффективной настройки таймингов, которая позволяет избежать лишней нагрузки на шлюз и исключить ошибки:

  1. Пауза перед первым опросом: Не запрашивайте результат немедленно. Оптимально делать первую попытку через 2–5 секунд после отправки.
  2. Интервалы повторов: Если статус остается IN_PROCESS, используйте экспоненциальную задержку. Например: 5 секунд, 15 секунд, 30 секунд, затем раз в минуту.
  3. Контрольный интервал: В критических случаях (как упоминалось в обсуждении) разница между запросом на создание ВСД и успешным получением ответа может достигать значительного времени. Рекомендуется настроить регламентное задание, которое будет «добирать» ответы по зависшим тикетам раз в 10–15 минут.

Защита от дублей с помощью applicationId

Главным инструментом идемпотентности в ВетИС является applicationId. Рассмотрим, как правильно его использовать в коде 1С. При формировании XML-запроса вы генерируете уникальный GUID для каждой транзакции. Этот GUID должен быть жестко привязан к документу-основанию (например, к РеализацияТоваровУслуг) в вашей базе данных.

Если в процессе обмена произошел сбой (сетевая ошибка, 504, падение сеанса 1С), при повторной попытке отправки обязательно используйте тот же самый applicationId, который был сгенерирован в первый раз. В этом случае ВетИС поймет, что это повтор старой заявки, и просто вернет уже существующий результат, не создавая новый документ.

Пример логики обработки (псевдокод):


Если НЕ ЗначениеЗаполнено(Объект.ИдентификаторЗаявкиВетИС) Тогда
    Объект.ИдентификаторЗаявкиВетИС = Новый УникальныйИдентификатор();
КонецЕсли;

ЗапросXML = СформироватьЗапросОформленияВСД(Объект, Объект.ИдентификаторЗаявкиВетИС);
РезультатОтправки = ОтправитьЗапросНаШлюз(ЗапросXML);

Если РезультатОтправки.СтатусКод = 504 Тогда
    // Запускаем механизм проверки по ИдентификаторЗаявкиВетИС через некоторое время
    РегистрироватьНеобходимостьПроверкиСтатуса(Объект);
КонецЕсли;

Что делать, если GUID тикета потерян?

Бывают ситуации, когда 1С отправила запрос, шлюз его принял, но в момент записи ответа произошел критический сбой базы данных. В итоге в 1С нет GUID тикета, а ВСД в «Меркурии» уже создан. Рассмотрим, как найти «потеряшку»:

Используйте метод getUnitShipmentList. Сформируйте запрос по следующим фильтрам:

Проанализировав список полученных документов, вы сможете найти нужный ВСД, получить его GUID и привязать к документу в 1С, восстановив целостность данных.

Итоги и рекомендации

Для стабильной работы асинхронного обмена придерживайтесь следующих правил:

Следуя этим рекомендациям, вы сможете построить отказоустойчивую систему взаимодействия с ВетИС, которая будет корректно обрабатывать даже самые сложные ситуации на стороне шлюза.

← На главную