Перейти к основному содержимому

Отладка и частые ошибки

Что делать, когда плагин не собирается, не устанавливается, не запускается или делает не то.

Где смотреть, что происходит​

Статус плагина​

Системная консоль > Плагины > Управление плагинами, список Установленные плагины:

Надпись под плагиномЧто значит
Этот плагин работает.Всё в порядке
Этот плагин не включен.Плагин выключен. Нажмите Включить
Не удалось запустить этот плагин.Серверная часть не стартовала. Причина — в логах сервера
Этот плагин несколько раз падал и больше не работает.Серверная часть падает сразу после запуска. Ищите panic в логах сервера

Логи​

Всё, что серверная часть пишет через p.API.LogInfo, p.API.LogError и т. п., а также ошибки запуска и паники попадают в лог сервера Loop:

  • Системная консоль > Отчеты > Журнал сервера — последние записи прямо в интерфейсе. Ищите по ID плагина: у каждой записи плагина есть поле plugin_id.
  • Файл logs/mattermost.log в папке сервера или вывод docker logs <контейнер> — если Loop запущен в Docker.

По умолчанию в лог не попадают сообщения уровня Debug. Чтобы их видеть, системный администратор включает Системная консоль > Окружение > Ведение журнала > Файловый уровень логирования (или Уровень логирования в консоли) = DEBUG.

Консоль браузера​

Ошибки клиентской части видны в инструментах разработчика браузера: F12 (⌥⌘I в macOS), вкладка Console. Там же удобно проверить, загрузился ли плагин:

window.plugins['ru.mycompany.hello']

Если в ответ undefined — клиентская часть не загрузилась. Посмотрите ошибки выше в консоли.

Запросы к серверной части плагина видны на вкладке Network: фильтруйте по /plugins/.

Проверка HTTP API без интерфейса​

Маршруты серверной части можно вызвать из терминала с персональным токеном:

curl -H "Authorization: Bearer ваш-токен" \
https://your-loop-server.ru/plugins/ru.mycompany.hello/stats

Частые ошибки​

Сборка​

СообщениеПричина и решение
go is not availableGo не установлен или не найден. Установите Go и проверьте go version в новом окне терминала
go: go.mod requires go >= 1.24.3 (running go 1.xx; GOTOOLCHAIN=local)Слишком старая версия Go. Обновите Go или уберите GOTOOLCHAIN=local из окружения — тогда Go сам скачает нужную версию
This project's package.json defines "packageManager": "yarn@4..." или yarn: command not foundНе включён Yarn 4. Выполните corepack enable
npm is not availableНе установлен Node.js
Cannot parse id from plugin.jsonОшибка в plugin.json: лишняя или пропущенная запятая, кавычка. Проверьте файл любым валидатором JSON
failed to parse manifest: json: unknown field "..."В plugin.json поле с опечаткой или поле, которого нет в Loop
golangci-lint: command not found при make или make check-styleНе установлен линтер. Выполните make deps (или brew install golangci-lint). Собрать плагин можно и без него — командой make dist
Usage Error: Couldn't find a script named "build:watch" (или debug, test)Проект создан из старой версии шаблона. Добавьте в webapp/package.json в scripts: "build:watch": "vite build --watch", "debug": "vite build --minify false --sourcemap inline", "debug:watch": "vite build --minify false --sourcemap inline --watch", "test": "echo \"no webapp tests\""
error:0308010C:digital envelope routines::unsupportedБывает у старых плагинов на webpack с новым Node.js. Выполните export NODE_OPTIONS=--openssl-legacy-provider и повторите сборку

Установка​

СообщениеПричина и решение
«Включите загрузку плагинов в config.json» вместо кнопки загрузкиЗагрузка плагинов выключена. Нужно PluginSettings.EnableUploads = true в конфигурации сервера — см. Быстрый старт
Plugins and/or plugin uploads have been disabled при make deployТо же самое
MM_SERVICESETTINGS_SITEURL is not setНет файла .env или в нём не задан адрес сервера
one of MM_ADMIN_TOKEN or MM_ADMIN_USERNAME/MM_ADMIN_PASSWORD must be definedВ .env не задан токен
Invalid or expired session, please login again (код 401) при make deployТокен неверный или отозван. Выпустите новый
403 / «У вас нет соответствующих прав»Токен принадлежит пользователю без роли системного администратора
«Невозможно установить плагин. Плагин с таким же идентификатором уже установлен»При загрузке через консоль плагин с этим ID уже есть. Удалите старый или используйте make deploy — он заменяет плагин
Unable to find manifest for extracted plugin (часто на macOS)В архив попали служебные файлы macOS ._*. Шаблон их удаляет, но если собираете архив сами — выполните export COPYFILE_DISABLE=true перед упаковкой
Загрузка отклоняется, а в Управлении плагинами включено Требовать подпись плагинаПри этой настройке Loop принимает только подписанные плагины из магазина. Для своего плагина её нужно выключить
No signature when persisting plugin to filestore в логе (уровень warn)Это не ошибка: так Loop отмечает любой неподписанный плагин. Ничего делать не нужно
unsopported plugin server version в логеmin_server_version в plugin.json больше версии Loop. Верните 9.11.0 — см. Манифест

Запуск​

Если под плагином написано Не удалось запустить этот плагин., откройте журнал сервера и найдите записи с ID плагина. Типичные причины:

Что в логеПричина и решение
backend executable not found for environment: linux/arm64 или exec format errorНет серверной части под систему сервера. Скорее всего, в .env задан MM_SERVICESETTINGS_ENABLEDEVELOPER=true, а сервер на ARM. Уберите переменную и пересоберите
Текст вашей ошибки из OnActivateПлагин сам отказался запускаться: например, не заполнены обязательные настройки. Заполните их в Системная консоль > Плагины > «Ваш плагин» и включите плагин снова
panic: ... и стек вызововСерверная часть упала. Чаще всего это обращение к nil: например, к p.sdk или p.botUserID до того, как они заданы в OnActivate. Стек подскажет файл и строку
RPC call to <Метод> API failed: rpc: can't find method ...Плагин вызывает метод, которого нет в Loop. См. Совместимость с Mattermost

Работа​

ПроблемаПричина и решение
На slash-команду Loop отвечает «Команда с триггером '/hello' не найдена»Плагин не запущен или RegisterCommand вернул ошибку — проверьте статус и лог
Кнопка или панель не появиласьОткройте консоль браузера: ошибки при загрузке плагина видны там. Проверьте, что вызов registry.register... действительно выполняется (например, добавьте console.log). Обновите страницу с очисткой кеша (Ctrl+Shift+R)
Запрос к серверной части возвращает 401 Not authorizedЗапрос пришёл без пользователя. Из клиентской части отправляйте запросы через Client4 (см. Клиентская часть), снаружи — с токеном
Изменили код, а ничего не поменялосьПлагин не пересобран или браузер взял старую версию. Выполните make deploy, проверьте версию в списке плагинов и обновите страницу
Настройки не применяютсяИмя поля в Configuration не совпадает с key в plugin.json, или тип поля не тот (например, string для настройки bool)
Сообщение бота подписано «Кто-то», или реакция бота не видна у автора сообщенияИнтерфейс не успел подгрузить данные для события, пришедшего в реальном времени. Обновите страницу — всё появится. На других пользователей и на работу плагина это не влияет
Бот отвечает сам себе без концаВ хуке MessageHasBeenPosted нет проверки post.UserId == p.botUserID — плагин реагирует на собственные сообщения
Loop стал медленно отправлять сообщенияДолгая работа в MessageWillBePosted или другом хуке ...Will.... Вынесите её в MessageHasBeenPosted или в горутину

Локальный режим​

Если сервер Loop запущен на том же компьютере, где вы разрабатываете, токен можно не создавать. Включите в конфигурации сервера локальный режим — ServiceSettings.EnableLocalMode = true (или переменная MM_SERVICESETTINGS_ENABLELOCALMODE=true) — и перезапустите Loop.

Сервер создаст сокет /var/tmp/mattermost_local.socket, и make deploy будет загружать плагин через него без авторизации. Если сокет лежит в другом месте, укажите путь в .env: MM_LOCALSOCKETPATH=/путь/к/сокету.

warning

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

Пошаговая отладка серверной части​

Обычно хватает логов. Но если нужно остановить плагин на строке и посмотреть значения переменных, используйте отладчик Delve. Это работает, только когда сервер Loop запущен на том же компьютере, что и отладчик.

1. Подготовьте сервер​

Отладчик останавливает плагин, а Loop считает остановившийся плагин зависшим и перезапускает его. Чтобы этого не было:

  1. В config.json сервера установите PluginSettings.EnableHealthCheck в false.

    Теперь Loop не будет перезапускать упавший плагин, и в списке он будет со статусом Работает, даже если упал. Во время отладки следите за логами.

  2. Отключите проверку связи в библиотеке go-plugin, через которую Loop общается с плагинами. Узнайте её версию в server/go.mod репозитория сервера (строка github.com/hashicorp/go-plugin) и выполните скрипт:

    patch_go_plugin.sh
    GO_PLUGIN_PACKAGE_VERSION=$1
    GO_PLUGIN_RPC_CLIENT_PATH=$(go env GOPATH)/pkg/mod/github.com/hashicorp/go-plugin@${GO_PLUGIN_PACKAGE_VERSION}/rpc_client.go

    if ! grep -q 'mux, err := yamux.Client(conn, nil)' "$GO_PLUGIN_RPC_CLIENT_PATH"; then
    echo "Файл уже изменён или строка не найдена"
    exit 0
    fi

    chmod u+w "$GO_PLUGIN_RPC_CLIENT_PATH"
    sed -i '' '/import (/a\
    "time"' "$GO_PLUGIN_RPC_CLIENT_PATH"
    sed -i '' '/mux, err := yamux.Client(conn, nil)/c\
    sessionConfig := yamux.DefaultConfig()\
    sessionConfig.EnableKeepAlive = false\
    sessionConfig.ConnectionWriteTimeout = time.Minute * 5\
    mux, err := yamux.Client(conn, sessionConfig)' "$GO_PLUGIN_RPC_CLIENT_PATH"
    echo "Готово"
    chmod +x patch_go_plugin.sh
    ./patch_go_plugin.sh v1.6.1 # подставьте версию из server/go.mod

    Скрипт написан для macOS; на Linux замените sed -i '' на sed -i.

  3. Пересоберите и перезапустите сервер Loop.

Только для разработки

Эти изменения ослабляют защиту сервера от зависших плагинов. Никогда не делайте их на рабочем сервере.

2. Подключите отладчик​

  1. Установите Delve: go install github.com/go-delve/delve/cmd/dlv@latest.

  2. Соберите плагин без оптимизаций и установите его:

    MM_DEBUG=true make deploy
  3. В отдельном терминале подключите отладчик к процессу плагина:

    make attach-headless

    Delve будет ждать подключения на порту 2346. Чтобы отлаживать прямо в терминале, вместо этого выполните make attach.

  4. В VS Code добавьте в .vscode/launch.json конфигурацию и запустите её на вкладке Run and Debug:

    .vscode/launch.json
    {
    "version": "0.2.0",
    "configurations": [
    {
    "name": "Attach to Loop plugin",
    "type": "go",
    "request": "attach",
    "mode": "remote",
    "port": 2346,
    "host": "127.0.0.1",
    "apiVersion": 2
    }
    ]
    }

    В GoLand то же самое делается через Run > Edit Configurations > Go Remote с портом 2346.

Теперь точки остановки в коде плагина срабатывают. Если что-то пошло не так, отключите отладчик в IDE и выполните make reset — он перезапустит плагин и завершит процессы Delve.

Отладка клиентской части​

  • Ставьте console.log и debugger — они работают как в любом веб-приложении.
  • Соберите плагин с MM_DEBUG=true make deploy: код не будет сжат, и в инструментах разработчика на вкладке Sources будут видны ваши исходники.
  • Установите расширение React Developer Tools, чтобы смотреть свойства и состояние компонентов, и Redux DevTools, чтобы видеть действия и данные хранилища — включая хранилище плагина plugins-<ID плагина>.

Доступ к локальному серверу из интернета​

Если плагин получает вебхуки от внешнего сервиса (GitHub, CRM) или использует вход через OAuth, внешний сервис должен достучаться до вашего сервера Loop. Локальный сервер можно временно открыть в интернет через туннель, например ngrok:

ngrok http 8065

Команда выведет адрес вида https://xxxx.ngrok-free.app. Укажите его в Системная консоль > Окружение > Веб-сервер > Адрес сайта, войдите в Loop по этому адресу и используйте его в настройках внешнего сервиса. На бесплатном тарифе адрес меняется при каждом запуске — не забывайте обновлять его в настройках. Запросы и ответы видны в инспекторе ngrok по адресу http://localhost:4040.

Бесплатная альтернатива без регистрации — ssh -R 80:localhost:8065 localhost.run.