Где сломалось: от текста ошибки до строки модуля в 1С 8.3

· 10 мин

Содержание

Чтобы найти ошибку в коде 1С, начните не с отладчика, а с подробного текста ошибки: в нём уже есть имя модуля и номер строки, например {ОбщийМодуль.ОбщегоНазначения.Модуль(1234)}. Откройте этот модуль в Конфигураторе, перейдите к строке через Ctrl+G и поставьте на ней точку останова. Часто этого уже хватает, чтобы увидеть причину.

Частое заблуждение — искать причину там, где ошибка всплыла. Строка из сообщения показывает место, где платформа споткнулась, а не место, где испортились данные. Пустая ссылка могла прийти из документа, записанного неделю назад. Поэтому диагностика идёт от симптома назад: текст → стек → данные → код, который эти данные сформировал.

Текст ошибки, стек вызовов и журнал регистрации

Короткое окно с ошибкой в режиме «Предприятие» почти бесполезно. Нужна подробная версия.

Как получить подробный текст

  1. В окне ошибки нажмите ссылку «Подробнее» или «Подробный текст ошибки».
  2. Скопируйте весь текст целиком, а не только первую строку.
  3. Найдите в нём фрагменты в фигурных скобках. Каждый — один уровень стека: объект метаданных, модуль, номер строки.

Пример разбора:

{ОбщийМодуль.РаботаСДокументами.Модуль(215)}: Ошибка при вызове метода контекста (Записать)
{Документ.РеализацияТоваровУслуг.МодульОбъекта(88)}: Значение не является значением объектного типа (Контрагент)

Читается снизу вверх. Самая глубокая строка — место сбоя: в модуле объекта документа, строка 88, код обратился к реквизиту через точку, а Контрагент оказался пустым или Неопределено.

Что означают частые тексты

  • 🔴 Значение не является значением объектного типа — обращение через точку к пустой ссылке, Неопределено или примитивному значению.
  • 🔴 Поле объекта не обнаружено — реквизита с таким именем нет у этого объекта. Часто бывает после обновления, когда реквизит переименовали.
  • 🔴 Индекс находится за границами массива — неверный расчёт границы цикла или пустая коллекция.
  • 🔴 Метод объекта не обнаружен — метод вызывают не у того типа или в недоступном контексте (серверный метод с клиента).
  • 🔴 Ошибка преобразования данных XDTO — сбой обмена, смотрите объект и поле, которые указаны в тексте.

Журнал регистрации: когда пользователь окно уже закрыл

В типовых конфигурациях на БСП журнал открывается через Администрирование → Обслуживание → Журнал регистрации. В Конфигураторе — Администрирование → Журнал регистрации.

Как искать быстро:

  • поставьте отбор по уровню «Ошибка»;
  • ограничьте интервал временем, которое назвал пользователь, плюс-минус 10 минут;
  • добавьте отбор по пользователю;
  • откройте событие двойным щелчком — в поле комментария лежит тот же стек с номерами строк.

Если ваш код перехватывает исключения в Попытка…Исключение, без записи в журнал ошибка исчезает бесследно. Пишите её явно:

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

ВызватьИсключение без параметров в блоке Исключение пробрасывает исходную ошибку дальше. Без него вызывающий код решит, что запись прошла успешно.

Отладчик 1С: пошаговый разбор проблемного места

Отладчик отвечает на вопрос «какие значения были у переменных в момент сбоя». Текст ошибки на это не отвечает.

Запуск отладки

  1. Откройте базу в Конфигураторе.
  2. Запустите Отладка → Начать отладку → Тонкий клиент (или F5, если клиент выбран в параметрах).
  3. Поставьте точку останова на нужной строке клавишей F9.
  4. Повторите в открывшемся «Предприятии» действие, которое даёт ошибку.

Для файловой базы этого достаточно. Для клиент-серверной базы отладка серверного кода должна быть разрешена на сервере: служба агента запускается с ключом -debug. Если ключа нет, точки останова в серверных модулях не сработают.

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

Основные приёмы

ДействиеКлавишаЗачем
Точка остановаF9Остановиться на строке
Шагнуть черезF10Выполнить строку, не заходя в вызываемую процедуру
Шагнуть вF11Зайти внутрь вызываемой процедуры
ПродолжитьF5Идти до следующей точки останова
Вычислить выражениеShift+F9Посмотреть значение переменной или выражения

Ещё три приёма, без которых отладка затягивается:

  • 🎯 Остановка по ошибке. Отладка → Остановка по ошибке — отладчик сам встанет на строке, где возникло исключение. Не нужно угадывать, куда ставить точку.
  • 🎯 Точка останова с условием. Если цикл проходит 5000 строк, а ломается одна, задайте условие вроде Строка.Номенклатура.Пустая(). Отладчик остановится только на нужной итерации.
  • 🎯 Стек вызовов. В окне стека видно, кто вызвал текущую процедуру и с какими параметрами. Так находят место, где «испортилось» значение.

Фоновые задания и обработчики на сервере

Код регламентных и фоновых заданий в сеансе пользователя не выполняется. Чтобы отладчик к ним подключился, откройте Отладка → Подключение, затем настройку автоматического подключения, и отметьте фоновые задания. После этого точки останова в коде задания сработают при его следующем запуске.

Поиск ошибок в запросах и в данных

Ошибки запросов делятся на две группы: запрос не выполняется вовсе или выполняется, но возвращает не то.

Синтаксическая ошибка

Платформа указывает позицию в тексте запроса:

{(12, 5)}: Поле не найдено "Номенклатура.Артикл"

Первое число — строка текста запроса, второе — символ. Считайте строки от начала текста запроса, а не модуля. Самый быстрый путь — скопировать текст в консоль запросов и открыть конструктор: он подсветит ошибочное поле.

Запрос работает, но данные неверные

Значит, ошибка логическая. Типичные причины:

  • 📌 Дубли строк. Левое соединение с табличной частью или регистром без отбора по ключу размножает записи. Сумма вырастает ровно в число совпадений.
  • 📌 Пропали строки. Внутреннее соединение отбрасывает записи без пары. Или условие на поле из левой таблицы поставлено в ГДЕ, и левое соединение фактически стало внутренним.
  • 📌 NULL вместо нуля. Поле из присоединённой таблицы, для которой пары не нашлось, равно NULL. Арифметика с ним даёт NULL. Лечится ЕСТЬNULL(Поле, 0).
  • 📌 Остатки «не те». Отбор по виртуальной таблице поставлен в ГДЕ, а не в её параметрах. Результат может отличаться, а запрос работает дольше.

Как проверить запрос из кода

  1. Остановитесь отладчиком сразу после строки Запрос.Выполнить().
  2. Через «Вычислить выражение» получите Запрос.Текст и значения параметров.
  3. Перенесите текст и параметры в консоль запросов и выполните там.
  4. Упрощайте запрос по частям: уберите соединения, затем условия, пока результат не станет правильным. Последняя убранная часть и есть причина.

Если запрос собирается в коде из кусков строк, ошибка часто в пропущенном пробеле или переносе на стыке. Смотрите итоговый Запрос.Текст, а не исходный код сборки.

Ошибки прав доступа и ограничений RLS

Ошибка с текстом Нарушение прав доступа! или Недостаточно прав — сигнал, что код нормальный, а у пользователя нет права на объект или запись.

Как отличить права от ошибки в коде

  1. Повторите действие под администратором.
  2. Не воспроизводится — проблема в правах. Воспроизводится — ищите в коде.
  3. В журнале регистрации ищите события доступа с отказом за нужный интервал: там указан объект, к которому не пустили.

Особенности RLS

Ограничения на уровне записей (RLS) ведут себя по-разному в зависимости от того, как написан запрос:

  • в запросе с ВЫБРАТЬ РАЗРЕШЕННЫЕ недоступные записи просто не попадут в результат;
  • в запросе без РАЗРЕШЕННЫЕ попытка прочитать запрещённую запись вызовет ошибку прав.

Отсюда частая ситуация: у администратора отчёт строится, у менеджера падает. Проверьте, есть ли РАЗРЕШЕННЫЕ во всех запросах, включая вложенные и пакетные.

Обратная ситуация: отчёт не падает, но показывает меньше данных. Это тоже RLS, только с РАЗРЕШЕННЫЕ. Пользователь видит часть записей, и итоги «не сходятся» с итогами администратора.

В типовых конфигурациях на БСП в карточке пользователя есть отчёт о правах доступа. Он показывает, какие роли и профили групп доступа дают или не дают право на конкретный объект. Список пользователей открывается из раздела Администрирование → Настройки пользователей и прав.

Привилегированный режим в коде отключает проверку прав. Если ошибка «ушла» после его включения, вы не исправили её, а спрятали. Сначала выясните, какого права не хватает и должно ли оно у пользователя быть.

Тормоза и блокировки: замер производительности и технологический журнал

Ошибка не всегда выглядит как окно с текстом. Иногда документ проводится две минуты или падает по таймауту.

Замер производительности

В Конфигураторе во время отладки включите Отладка → Замер производительности. Выполните медленное действие и остановите замер. Платформа покажет по строкам кода:

  • сколько раз выполнялась строка;
  • сколько времени заняла;
  • какой процент от общего времени.

Как правило, основное время съедают одна-две строки. Чаще всего это запрос внутри цикла или обращение через точку к реквизиту ссылки в цикле — каждое такое обращение читает объект из базы.

Конфликт блокировок

Типовые тексты:

  • Конфликт блокировок при выполнении транзакции: Превышено максимальное время ожидания предоставления блокировки;
  • сообщения о взаимоблокировке (deadlock), когда две транзакции ждут друг друга.

Первый случай значит, что ваша транзакция ждала, пока чужая отпустит те же данные. Ищите длинную транзакцию: проведение большого документа, групповую обработку, обмен. Второй — две транзакции захватывают одни и те же данные в разном порядке.

Технологический журнал

Когда журнал регистрации молчит, включают технологический журнал. Его настраивает файл logcfg.xml в каталоге conf установленной платформы. Минимальная настройка для ошибок и блокировок:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
  <log location="C:\techlog" history="24">
    <event>
      <eq property="name" value="EXCP"/>
    </event>
    <event>
      <eq property="name" value="TLOCK"/>
    </event>
    <event>
      <eq property="name" value="TTIMEOUT"/>
    </event>
    <event>
      <eq property="name" value="TDEADLOCK"/>
    </event>
    <property name="all"/>
  </log>
</config>
  • EXCP — исключения, включая те, что не дошли до пользователя;
  • TLOCK — управляемые блокировки;
  • TTIMEOUT — ожидание блокировки завершилось таймаутом;
  • TDEADLOCK — взаимоблокировка.

Параметр history задаёт, сколько часов хранить логи.

Техжурнал быстро занимает диск. На нагруженном сервере событие TLOCK пишет гигабайты за час. Включайте его на время воспроизведения, затем удаляйте или переименовывайте logcfg.xml. Платформа подхватывает изменения файла без перезапуска.

Сужаем круг: расширения, внешние обработки, изменённая конфигурация

Когда стек ведёт в типовой модуль, а у соседних организаций всё работает, причина часто не в типовом коде.

Что проверить по очереди:

  1. Расширения конфигурации . В БП 3.0 и ЗУП 3.1 список открывается в разделе Администрирование → Печатные формы, отчеты и обработки → Расширения. Отключите подозрительное расширение в копии базы и повторите действие. Ушла ошибка — смотрите код расширения.
  2. Внешние обработки и печатные формы. Стек с именем внешней обработки сразу указывает на виновника. Её код смотрят, открыв файл .epf в Конфигураторе через меню «Файл».
  3. Доработки типовой конфигурации. Сравните конфигурацию базы с поставкой: Конфигурация → Сравнить конфигурации. Изменённые модули рядом со строкой из стека — первые подозреваемые.
  4. Синтаксис после правок. Конфигурация → Проверка конфигурации находит ошибки компиляции во всех модулях, а не только в открытом.

Деление пополам

Если причину не видно, применяйте бисекцию. Закомментируйте половину подозрительного блока, проверьте. Ошибка осталась — она в оставшейся половине. Ушла — в убранной. За 5–6 итераций блок в 100 строк сужается до 2–3 строк.

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

Чек-лист быстрой диагностики сбоя

Порядок важен: каждый шаг дешевле следующего. Отмечайте пройденное.

Диагностика ошибки в коде 1С
Выполнено: 0 / 10

Если все пункты пройдены, а причина не найдена, ошибка, скорее всего, в данных. Найдите конкретный документ или элемент справочника, на котором она возникает, и сравните его с похожим «рабочим» объектом по реквизитам.

Частые вопросы

Почему ошибка есть у пользователя, а у меня в отладке её нет?
Обычно разные права, разные данные или разный клиент. Запустите отладку под этим пользователем, на той же копии базы и в том же клиенте — тонком или веб.
Можно ли отлаживать прямо в рабочей базе?
Технически да, но во время остановки на точке транзакция и блокировки удерживаются, и коллеги будут ждать. Разбирайте ошибку на свежей копии базы.
Ошибка возникает раз в неделю и не воспроизводится. Что делать?
Добавьте запись в журнал регистрации с подробным представлением ошибки в нужном месте кода и включите технологический журнал с событием EXCP. Следующий сбой оставит полный след.
Номер строки в стеке не совпадает с кодом. Почему?
Код в базе отличается от открытого: не обновлена конфигурация базы данных или ошибка в расширении. Проверьте, что основная конфигурация совпадает с конфигурацией базы данных.
Чем журнал регистрации отличается от технологического журнала?
Журнал регистрации пишет прикладные события и ошибки, которые видит пользователь. Технологический журнал пишет внутренние события платформы: исключения, блокировки, запросы к СУБД. Его включают точечно, на время разбора.