Обработка ошибок
Какие ошибки перехватывает ядро и как плагинам обрабатывать ошибки в экспортируемых методах.
Plugify по-разному обрабатывает ошибки в двух местах: пока загружает и ведёт расширения и пока плагины вызывают друг друга.
Ошибки, которые обрабатывает ядро
Ядро проверяет всё, что делает с расширением: чтение манифеста, разрешение зависимостей, загрузку, экспорт, запуск, обновление и остановку. Языковой модуль сообщает о сбое, возвращая ошибку из соответствующего метода ILanguageModule; исключение, выброшенное из этих методов, перехватывается и обрабатывается так же. Расширение получает состояние Failed (или Corrupted, Unresolved, Disabled) с причиной, зависящие от него расширения получают Skipped, а остальные продолжают работать. После загрузки ядро пишет в лог отчёт с причиной по каждому незапущенному расширению.
Вызовы между плагинами
Когда плагин вызывает метод другого плагина, вызов идёт прямо в нативную функцию этого метода. Ядро между ними не стоит, благодаря этому вызовы быстрые, но это значит и то, что ядро их не проверяет. Что происходит при ошибке, зависит от языка вызванного метода:
- Нативный код (C++, Go, Rust): падение в методе — это падение процесса. Исключение C++ не должно выходить из экспортируемой функции.
- Языки со средой выполнения (C#, Python, JavaScript, Lua): языковой модуль перехватывает ошибку кода плагина, пишет её в лог и возвращает вызывающему значение по умолчанию (ноль, пустую строку и т. п.). Вызывающий не узнаёт, что вызов не удался.
Рекомендации для экспортируемых методов
Проверяйте аргументы
Проверяйте диапазоны, размеры и хэндлы в начале каждого экспортируемого метода. Другой плагин может передать всё, что допускает сигнатура.
Сообщайте о сбое через возвращаемое значение
Раз ошибка не доходит до вызывающего, сделайте её частью сигнатуры: возвращайте bool или код ошибки, а результаты передавайте через ref-параметры.
Не выпускайте ошибки наружу
В C++ перехватывайте исключения внутри экспортируемой функции. В языках с исключениями перехватывайте то, что можете обработать, и возвращайте результат, который вызывающий может проверить.
Описывайте условия ошибок
Пишите в description метода и его параметров, что он возвращает при сбое. Генераторы биндингов переносят эти описания в код, который видят другие плагины.