Разработка HTTP-сервисов в среде 1С:Предприятие 8.3 часто сопровождается трудностями, связанными с диагностикой ошибок. В отличие от обычных сеансов пользователей, ошибки в коде HTTP-сервисов нередко происходят «молчаливо»: внешняя система получает статус 500, а в Журнале регистрации 1С не появляется никакой информации о причинах сбоя. В этой статье мы подробно разберем, как наладить стабильное логирование и сделать процесс отладки предсказуемым.
Проанализируем ситуацию: когда выполнение кода внутри метода HTTP-сервиса прерывается из-за критической ошибки (например, обращение к несуществующему реквизиту или деление на ноль), платформа 1С на уровне веб-расширения перехватывает это исключение и просто возвращает клиенту стандартный ответ об ошибке сервера. При этом запись в стандартный ЖурналРегистрации автоматически не создается, так как контекст исполнения считается «служебным». Для решения этой проблемы нам необходимо внедрить механизмы явного перехвата исключений.
Самый простой и быстрый способ не потерять описание ошибки — обернуть основной вызов логики в конструкцию Попытка...Исключение. Рассмотрим пример реализации непосредственно в методе HTTP-сервиса:
Функция ИмяМетодаГЕТ(Запрос)
Попытка
// Вызываем основную логику обработки
Результат = ОбщийМодульСервисов.ОбработатьЗапрос(Запрос);
Возврат Результат;
Исключение
// Формируем подробное описание ошибки
ТекстОшибки = ИнформацияОбОшибке().Описание;
ПодробноеОписание = ИнформацияОбОшибке().ПодробноеОписание;
// Записываем событие в Журнал регистрации
ЗаписьЖурналаРегистрации(
"HTTP-сервис.ИмяСервиса",
УровеньЖурналаРегистрации.Ошибка,
,,
"Произошла критическая ошибка: " + ТекстОшибки + Символы.ПС + ПодробноеОписание
);
// Возвращаем клиенту понятный ответ
Ответ = Новый HTTPСервисОтвет(500);
Ответ.УстановитьТелоИзСтроки("Internal Server Error: " + ТекстОшибки);
Возврат Ответ;
КонецПопытки;
КонецФункции
Для крупных проектов писать блоки Попытка в каждом методе неудобно. Разберем более продвинутый подход: вынос всей логики в отдельный ОбщийМодуль. Это позволяет тестировать функционал с помощью обычных внешних обработок, не обращаясь к веб-серверу, что значительно упрощает отладку.
Рассмотрим структуру метода, который возвращает результат в формате JSON и самостоятельно обрабатывает свои ошибки:
Функция ОбработкаДанных(DATA) Экспорт
Попытка
// Здесь выполняется вся тяжелая бизнес-логика
РезультатОбработки = ВыполнитьСложныеДействия(DATA);
ОтветСтруктура = Новый Структура("Success, Data", Истина, РезультатОбработки);
Исключение
// Логируем ошибку внутри модуля
Подробности = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации("API.Обработка", УровеньЖурналаРегистрации.Ошибка,,, Подробности);
// Формируем структуру ответа с описанием ошибки для клиента
ОтветСтруктура = Новый Структура("Success, Error", Ложь, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
// Преобразуем результат в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ОтветСтруктура);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
При таком подходе в самом HTTP-сервисе остается только минимальный код-обертка, который считывает тело запроса и возвращает сформированную строку JSON. Вероятность того, что ошибка возникнет вне блока Попытка, сводится к минимуму.
Если сервис «крашится» настолько серьезно, что даже код внутри блока Исключение не успевает отработать (например, при падении рабочего процесса rphost), на помощь приходит Технологический журнал. Выясним причину через настройку файла logcfg.xml.
Для отслеживания исключений в HTTP-сервисах необходимо настроить сбор события EXCP. Пример минимального конфига:
<config xmlns="http://v8.1c.ru/7.1/logcfg">
<log location="C:\LOGS\HTTP_ERRORS" history="24">
<event>
<eq property="Name" value="EXCP"/>
</event>
<property name="All"/>
</log>
</config>
Этот файл заставит платформу записывать абсолютно все исключительные ситуации в указанную папку. Там вы сможете найти дампы ошибок, даже если 1С не смогла ничего записать в обычный лог.
Многие разработчики жалуются, что при установке точки останова в методе HTTP-сервиса отладчик постоянно «перехватывает» новые запросы, не давая работать с текущим. Разберем по шагам, как это исправить:
activityTimeout в секции FastCGI. Для Apache проверьте директиву Timeout.Проанализируем спорную ситуацию из практики: какой код ответа возвращать, если тело запроса пустое или данные некорректны? Использование кода 405 (Method Not Allowed) для индикации отсутствия данных является ошибкой. Согласно стандартам RFC:
POST там, где разрешен только GET.Правильная обработка статус-кодов помогает внешним системам автоматически определять, нужно ли повторять запрос или проблема в самих данных.
Резюмируя: для комфортной работы с HTTP-сервисами всегда выносите логику в общие модули, используйте явную обработку исключений с записью в ЖурналРегистрации и не забывайте про возможности Технологического журнала для диагностики самых сложных случаев.