Почему веб-сервис 1С возвращает ошибку 500 Internal Server Error при создании документов и как её исправить?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При интеграции сторонних систем с 1С через SOAP/REST веб-сервисы разработчики часто сталкиваются с ситуацией, когда одни объекты конфигурации создаются без проблем, а при попытке программно создать другие документы сервер мгновенно возвращает 500 Internal Server Error. При этом стандартная конструкция Попытка ... Исключение внутри метода веб-сервиса не перехватывает исключение, а журнал регистрации остается пустым.

В этой статье мы подробно разберем, как локализовать подобную ошибку, настроить подробный вывод сообщений об ошибках в IIS и исправить проблемы контекста исполнения кода на стороне 1С.

1. Включение детализации ошибок на веб-сервере IIS

По умолчанию веб-сервер IIS при возникновении критических сбоев в рабочем процессе 1С скрывает подробности и отдаёт клиенту лишь обобщённый статус HTTP 500. Чтобы увидеть реальный текст ошибки (SOAP Fault) и стек вызова, необходимо настроить параметр отображения ошибок виртуального приложения.

Рассмотрим пошагово порядок настройки в менеджере служб IIS:

  1. Откроем Диспетчер служб IIS (IIS Manager).
  2. В дереве подключений перейдем к нашему виртуальному приложению 1С: Имя сервера -> Сайты -> Default Web Site -> [Имя виртуального приложения].
  3. В основном окне открываем раздел Страницы ошибок (Error Pages).
  4. В правой панели действий нажимаем Изменить параметры настройки... (Edit Feature Settings...).
  5. В появившемся окне переключаем тумблер в положение Подробные ошибки (Detailed errors).
  6. Нажимаем ОК для сохранения изменений.

После этой настройки веб-сервис вместо обезличенной ошибки 500 начнет возвращать полноценное SOAP-сообщение с текстом исключения, возникшего на стороне 1С.

2. Анализ причин возникновения ошибки компиляции на сервере

Проанализируем пример текста ошибки, который возвращается в SOAP Fault после включения детализации:


<soap:Fault>
   <faultcode>soap:Client</faultcode>
   <faultstring>Неизвестная ошибка. {ОбщийМодуль.ОбщийДляНШ(9,118)}: Переменная не определена (РабочаяДата)</faultstring>
</soap:Fault>

Или другой вариант ошибки при создании документа:


<soap:Fault>
   <faultcode>soap:Client</faultcode>
   <faultstring>Неизвестная ошибка. {Документ.ЗаказПоставщику(297,53)}: Переменная не определена (ФормированиеПечатныхФорм)</faultstring>
</soap:Fault>

Выясним причину такого поведения. Сеанс веб-сервиса выполняется строго в серверном контексте. При выполнении кода создания нового документа (например, Документы.ЗаказПокупателя.СоздатьДокумент()) платформа производит синтаксическую проверку и компиляцию модуля объекта, модуля менеджера и связанных общих модулей.

Если в этих модулях присутствуют обращения к клиентским переменным или модулям, происходят критические сбои:

  1. Переменная РабочаяДата: является элементом глобального контекста клиентского приложения и полностью отсутствует в серверных сеансах, фоновых заданиях и веб-сервисах.
  2. Клиентские общие модули: если модуль (например, ФормированиеПечатныхФорм) не имеет установленного флага Сервер в свойствах или предназначен только для работы на клиенте, обращение к нему из серверного контекста приводит к ошибке компиляции «Переменная не определена».

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

3. Управление контекстом и исправление кода

Разберем способы устранения обнаруженных проблем в конфигурации 1С.

Шаг 1. Разделение клиентской и серверной логики директивами компиляции

Если в модуле объекта документа или общем модуле содержится код, обращающийся к интерфейсу или клиентским переменным, оборачиваем его в инструкции препроцессора:


#Если Клиент Тогда
    // Код, выполняемый только на клиенте
    ТекущаяДатаДокумента = РабочаяДата;
#Иначе
    // Серверный контекст (включая веб-сервисы)
    ТекущаяДатаДокумента = ТекущаяДатаСеанса();
#КонецЕсли

Шаг 2. Замена глобальной переменной РабочаяДата

В серверном коде вместо РабочаяДата необходимо использовать функцию ТекущаяДата() или ТекущаяДатаСеанса(). Если бизнес-логика требует использовать специфическую рабочую дату пользователя, её следует передавать явным образом в параметрах вызова метода веб-сервиса.

Шаг 3. Проверка свойств общих модулей

В конфигураторе найдем общие модули, на которые ссылается код документа, и проверим их свойства:

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

4. Оптимизация обращения к менеджерам объектов

Посмотрим на исходный код получения менеджера объекта из темы:


// Нерекомендуемый вариант: использование динамического Вычислить()
Спр = Вычислить("Документы." + name);
НовыйОбъект = Спр.СоздатьДокумент();

Использование функции Вычислить() ухудшает читаемость кода, затрудняет отладку и работает медленнее. Рекомендуется использовать прямое обращение к коллекциям метаданных через квадратные скобки:


// Рекомендуемый вариант: прямое обращение к коллекции по имени
МенеджерДокумента = Документы[name];
НовыйОбъект = МенеджерДокумента.СоздатьДокумент();

Если тип объекта заранее неизвестен, универсальную функцию создания объекта можно реализовать следующим образом:


Функция СоздатьНовыйОбъект(ИмяТипа, ИмяОбъекта)
    
    НовыйОбъект = Неопределено;
    
    Если ИмяТипа = "Справочник" Тогда
        НовыйОбъект = Справочники[ИмяОбъекта].СоздатьЭлемент();
    ИначеЕсли ИмяТипа = "Документ" Тогда
        НовыйОбъект = Документы[ИмяОбъекта].СоздатьДокумент();
    Иначе
        ВызватьИсключение "Неподдерживаемый тип объекта: " + ИмяТипа;
    КонецЕсли;
    
    Возврат НовыйОбъект;
    
КонецФункции

Применение этого подхода совместно с разделением клиентского и серверного контекста гарантирует стабильную работу веб-сервисов и корректную обработку SOAP-запросов.

← На главную