Перейти к содержанию

FAQ: Lua pcall + SMART:execute_action — какие ошибки перехватываются

Документ отвечает на вопросы администраторов и разработчиков о том, какие ошибки SMART:execute_action перехватываются конструкцией pcall, а какие — нет, и как правильно обрабатывать ошибки в Lua-скриптах. Типичные жалобы: «Обернул SMART:execute_action("CreateTask", ...) в pcall, но ошибка не ловится», «Lua-скрипт падает с необработанным исключением, хотя стоит pcall», «Как правильно обрабатывать ошибки при создании задач из Lua?»

Как работает перехват ошибок pcall

Конструкция pcall оборачивает вызов SMART:execute_action. Ошибки, возникшие при выполнении действия на стороне платформы, перехватываются и возвращаются в pcall как сообщение об ошибке. Ошибки до запуска (компиляция скрипта, преобразование параметров) до pcall не доходят.

Ошибки, которые pcall успешно перехватывает:

Тип ошибки Пример pcall ловит?
Ошибка в пользовательском Lua-коде nil + 1, обращение к nil-полю
Неверное имя действия execute_action("НесуществующееДействие", ...)
Неверный тип контекста execute_action("CreateTask", id, "unknown", ...)
Ошибка бизнес-логики при выполнении действия Валидация ДП, отсутствие прав
SQL-ошибки в SQL:query(), SQL:scalar() Синтаксическая ошибка в запросе
Ошибка при выполнении действия Исключение в процессе выполнения действия

Ошибки, которые pcall не перехватывает:

Тип ошибки Причина pcall ловит?
Синтаксическая ошибка Lua Ошибка при компиляции, до выполнения
Ошибка преобразования параметров Невозможность конвертации типов на границе Lua↔C#
Системное исключение среды (.NET 9) Исключение возникает до входа в обёртку перехвата
Ошибки в обработчиках исключений Если само сохранение исключения в Lua state падает

В .NET 9 изменилось поведение проброса исключений из движка Lua: системное исключение могло «терять» исходное сообщение. В текущих версиях 1Формы это компенсируется на стороне платформы — исходное сообщение об ошибке восстанавливается и доходит до pcall.

Паттерн обработки ошибок и асинхронные вызовы

Рекомендуемый подход — оборачивать вызов в pcall и проверять флаг успеха:

local success, result = pcall(function()
    return SMART:execute_action("CreateTask", nil, "task", {
        SubcatID = 123,
        TaskName = "Новая задача",
        -- ...параметры...
    })
end)

if not success then
    -- result содержит строку с сообщением об ошибке
    print("Ошибка создания задачи: " .. tostring(result))
    -- Можно записать в лог или выполнить альтернативное действие
else
    -- result содержит возвращённое значение (например, ID созданной задачи)
    print("Задача создана: " .. tostring(result))
end

Асинхронные вызовы (async = true) — особый случай: execute_action возвращает nil немедленно, ошибки происходят позже в фоне, pcall не перехватывает асинхронные ошибки. Для контроля используйте синхронный режим или проверяйте результат отдельно.

Частые причины «pcall не ловит» и отладка

Почему pcall может не поймать ошибку и что делать:

Ситуация Объяснение Решение
Синтаксическая ошибка в скрипте Скрипт не компилируется → pcall не вызывается Исправить синтаксис, проверить в тест-кейсах
Ошибка в коде ВНЕ pcall Исключение до/после блока pcall Обернуть весь код в pcall
Неверный тип параметра Не удаётся преобразовать тип → системное исключение Привести типы явно: tonumber(), tostring()
Ошибка при async=true Асинхронная ошибка не возвращается в pcall Использовать синхронный вызов для отладки

Тест-кейсы смарт-выражений (SmartExpressionTestCases в БД) позволяют тестировать Lua-скрипты: задать набор входных параметров, запустить скрипт в безопасном контексте, увидеть полный вывод (print) и исключения. API: GET /admin/smart/recurrences/execute/{id} — ручной запуск для проверки.

Разбор проблем и обращение в поддержку

Для разбора проблемы понадобятся: полный текст Lua-скрипта, сообщение об ошибке (из логов или интерфейса), ID задачи / категории, в контексте которой запускался скрипт, версия платформы (важно для .NET 9).

Когда обращаться в поддержку 1Ф:

  • Если pcall действительно не ловит ошибку внутри SMART:execute_action — возможная проблема среды, обратитесь в поддержку 1Ф
  • Если ошибка при компиляции скрипта — проверьте синтаксис
  • Если ошибка в бизнес-логике действия — проверьте настройки категории и ДП

Смежные разделы: Справочник смарт-действий — все действия и их параметры; Смарт-действия — администрирование.