← Назад к вопросам

Как расследуешь ошибки принимаемых запросов?

2.0 Middle🔥 241 комментариев
#Запросы и оптимизация#СУБД и хранение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Расследование ошибок принимаемых запросов

В 1С часто нужна интеграция через REST API или веб-сервисы. Когда внешние системы отправляют запросы, все может сломаться. Вот мой систематический подход.

Уровень 1: Логирование

Первое что делаю — логирую ВСЁ.

Процедура ОбработатьВходящийЗапрос(ДанныеЗапроса) Экспорт
    
    // Логируем исходные данные
    ЗаписьЖурнала.ЗаписатьДанные(
        "ВходящиеЗапросы",
        Новая Структура("ДанныеЗапроса,ВремяПолучения,Источник",
            ДанныеЗапроса,
            ТекущаяДата(),
            Метаданные.ВебСервис.Имя
        )
    );
    
    Попытка
        // Валидация
        ПроверитьДанные(ДанныеЗапроса);
        
        // Обработка
        РезультатОбработки = ОбработатьДанные(ДанныеЗапроса);
        
        // Логируем успех
        ЗаписьЖурнала.ЗаписатьСобытие(
            "ОбработкаЗавершена",
            "Успешно обработаны данные",,
            РезультатОбработки
        );
        
    Исключение
        // Логируем ошибку с полным контекстом
        ЗаписьЖурнала.ЗаписатьОшибку(
            "ОшибкаОбработкиЗапроса",
            ОписаниеОшибки(),
            Новая Структура("ДанныеЗапроса,ВремяОшибки",
                ДанныеЗапроса,
                ТекущаяДата()
            )
        );
    КонецПопытки;
    
КонецПроцедуры;

Уровень 2: Валидация на входе

Проверяю структуру данных перед обработкой.

Процедура ПроверитьДанные(ДанныеЗапроса) Экспорт
    
    // Проверка на пустоту
    Если ДанныеЗапроса = Неопределено Тогда
        ВызватьИсключение "Получены пустые данные от внешней системы";
    КонецЕсли;
    
    // Проверка обязательных полей
    ОбязательныеПоля = Новый Массив;
    ОбязательныеПоля.Добавить("КодКонтрагента");
    ОбязательныеПоля.Добавить("СуммаДокумента");
    ОбязательныеПоля.Добавить("Дата");
    
    Для Каждого ПолеИмя Из ОбязательныеПоля Цикл
        Если НЕ ДанныеЗапроса.Свойство(ПолеИмя) ИЛИ ДанныеЗапроса[ПолеИмя] = "" Тогда
            ВызватьИсключение "Отсутствует обязательное поле: " + ПолеИмя;
        КонецЕсли;
    КонецЦикла;
    
    // Проверка типов
    Если НЕ ЭтоЧисло(ДанныеЗапроса.СуммаДокумента) Тогда
        ВызватьИсключение "Сумма должна быть числом, получено: " + Тип(ДанныеЗапроса.СуммаДокумента);
    КонецЕсли;
    
    // Проверка диапазонов
    Если ДанныеЗапроса.СуммаДокумента <= 0 Тогда
        ВызватьИсключение "Сумма не может быть отрицательной или нулевой";
    КонецЕсли;
    
КонецПроцедуры;

Уровень 3: Трассировка с контекстом

Процедура ОбработатьДанные(ДанныеЗапроса) Экспорт
    
    ДополнительныйКонтекст = Новая Структура;
    ДополнительныйКонтекст.Вставить("ШагОбработки", "Инициализация");
    ДополнительныйКонтекст.Вставить("ВремяНачала", ТекущаяДата());
    
    Попытка
        
        // Шаг 1: Поиск контрагента
        ДополнительныйКонтекст.ШагОбработки = "Поиск контрагента";
        Контрагент = Справочники.Контрагенты.НайтиПоКоду(ДанныеЗапроса.КодКонтрагента);
        
        Если Контрагент.Пусто() Тогда
            ВызватьИсключение "Контрагент с кодом '" + ДанныеЗапроса.КодКонтрагента + "' не найден в системе";
        КонецЕсли;
        
        // Шаг 2: Валидация контрагента
        ДополнительныйКонтекст.ШагОбработки = "Валидация контрагента";
        Если Контрагент.ПометаНаУдаление Тогда
            ВызватьИсключение "Контрагент удалён";
        КонецЕсли;
        
        // Шаг 3: Создание документа
        ДополнительныйКонтекст.ШагОбработки = "Создание документа";
        ДокументОбъект = Документы.Счёт.СоздатьДокумент();
        ДокументОбъект.Контрагент = Контрагент;
        ДокументОбъект.Сумма = ДанныеЗапроса.СуммаДокумента;
        ДокументОбъект.Дата = ДанныеЗапроса.Дата;
        
        ДополнительныйКонтекст.ШагОбработки = "Запись документа";
        ДокументОбъект.Записать();
        
        ДополнительныйКонтекст.ШагОбработки = "Завершено";
        ДополнительныйКонтекст.ВремяЗавершения = ТекущаяДата();
        ДополнительныйКонтекст.ВремяОбработки = 
            (ДополнительныйКонтекст.ВремяЗавершения - ДополнительныйКонтекст.ВремяНачала) * 86400;
        
        ЗаписьЖурнала.ЗаписатьСобытие("УспешнаяОбработкаЗапроса", , , ДополнительныйКонтекст);
        
    Исключение
        ДополнительныйКонтекст.Ошибка = ОписаниеОшибки();
        ДополнительныйКонтекст.ВремяОшибки = ТекущаяДата();
        ЗаписьЖурнала.ЗаписатьОшибку(
            "ОшибкаПриОбработкеЗапроса",
            ОписаниеОшибки(),
            ДополнительныйКонтекст
        );
    КонецПопытки;
    
КонецПроцедуры;

Уровень 4: Анализ через журнал регистрации

Когда ошибка произошла, анализирую через интерфейс 1С:

// Примерный запрос для анализа
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ЖурналРегистрации.Время,
    |    ЖурналРегистрации.Сеанс,
    |    ЖурналРегистрации.Пользователь,
    |    ЖурналРегистрации.События,
    |    ЖурналРегистрации.Комментарий
    |ИЗ
    |    РегистрСведений.ЖурналРегистрации КАК ЖурналРегистрации
    |ГДЕ
    |    ЖурналРегистрации.Событие = 'ОшибкаОбработкиЗапроса'
    |    И ЖурналРегистрации.Время >= &ВремяСтарта
    |УПОРЯДОЧИТЬ ПО
    |    ЖурналРегистрации.Время УБЫВ
    |ПЕРВЫЕ 100";

Уровень 5: Внешние системы

Если ошибка на стороне отправителя:

// Проверяю что пришло от другой системы
Процедура ПроверитьИсточник(ДанныеЗапроса, ИсточникСистемы) Экспорт
    
    // Проверка аутентификации
    Если НЕ ПроверитьАутентификацию(ИсточникСистемы) Тогда
        ВызватьИсключение "Неверные учётные данные от " + ИсточникСистемы;
    КонецЕсли;
    
    // Проверка версии API
    Если ДанныеЗапроса.ВерсияAPI <> "1.0" Тогда
        // Может быть несовместимость
        СообщениеОшибки = "Несовместимая версия API: " + ДанныеЗапроса.ВерсияAPI;
        ЗаписьЖурнала.ЗаписатьПредупреждение("ОшибкаПротокола", СообщениеОшибки);
    КонецЕсли;
    
КонецПроцедуры;

Уровень 6: Инструменты для отладки

В режиме 1С:Предприятие:

  • Вид → Тестирование и отладка → Отладчик
  • Вид → Тестирование и отладка → Консоль

В кодировании:

// Временная отладочная выписка
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "DEBUG: " + ПредставлениеДанных(ДанныеЗапроса);
Сообщение.Сообщить();

Мой чеклист отладки

  • Проверил исходные данные в журнале
  • Прошелся по каждому шагу обработки (логирование)
  • Проверил ошибку в консоли отладчика
  • Воспроизвел ошибку вручную с теми же данными
  • Проверил версию API / протокол
  • Проверил права доступа пользователя
  • Проверил состояние БД (нет блокировок)
  • Посмотрел связанные изменения за последние дни

Вывод

Ключ к расследованию — логирование на каждом шаге. Когда ошибка произойдёт:

  1. Видишь где именно она случилась
  2. Видишь какие данные были
  3. Видишь когда это произошло
  4. Можешь воспроизвести локально

Это экономит часы дебага в будущем.