Снегопат https://snegopat.ru/forum/ |
|
Исключения (exceptions) и их отлов в скриптах https://snegopat.ru/forum/viewtopic.php?f=3&t=54 |
Страница 1 из 4 |
Автор: | kuntashov [ 31 окт 2011, 16:00 ] |
Заголовок сообщения: | Исключения (exceptions) и их отлов в скриптах |
Всем привет! Достаточно много возился в эти выходные со скриптами на 29 релизе (впрочем, пробовал и предыдущие), столкнулся с такой неприятной штукой. Если при вызове метода/макроса (далее - просто метод) одного скрипта из другого скрипта в вызываемом методе вызвано исключение (брошено явно или неявно), то в вызывающем методе это исключение при помощи конструкции try {} catch (e) {} никак не поймать В итоге оно всплывает на самый верх и нам всплывает стандартное окно с исключением и предложением запустить отладчик. Кто-нибудь сталкивался с этим? Нашли какое-нибудь решение? Саша, не подскажешь, есть ли возможность поймать исключение в описанной ситуации? Для того, чтобы воспроизвести ситуацию прилагаю код простейших скриптов: lib.js - скрипт, чей метод вызывается из другого скрипта Код: $engine JScript $uname testExceptionsLib function throwErrorFunction() { throw "Excepiton from testExceptionsLib.throwErrorFunction()"; } function macrosThrowErrorMacros() { throw "Excepiton from testExceptionsLib.throwErrorMacros()"; } app.js - скрипт, в макросе которого вызываем метод из lib.js и пытаемся обработать его исключение Код: $engine JScript $uname testExceptionsApp var lib = addins.byUniqueName("testExceptionsLib"); function macrosИсключениеПриВызовеФункции() { try { lib.object.throwErrorFunction(); } catch (e) { Message("Gotcha: " + e.text); } } function macrosИсключениеПриПрограммномВызовеМакроса() { try { lib.invokeMacros("ThrowErrorMacros"); } catch (e) { Message("Gotcha: " + e.text); } } p.s. В порыве экспериментов я начерно портировал JsUnit (http://jsunit.net) под Снегопат и даже "нарисовал" простейший запускатель тестов, и оно даже работает, за исключением того, что первый же сломавшийся тест останавливает выполнение всех тестов из-за озвученной проблемы (assert'ы бросают исключения). |
Автор: | artbear [ 31 окт 2011, 16:25 ] |
Заголовок сообщения: | Re: Исключения (exceptions) и их отлов в скриптах |
kuntashov писал(а): В порыве экспериментов я начерно портировал JsUnit (http://jsunit.net) под Снегопат и даже "нарисовал" простейший запускатель тестов, и оно даже работает, за исключением того, что первый же сломавшийся тест останавливает выполнение всех тестов из-за озвученной проблемы (assert'ы бросают исключения). А я в свое время пару часов попытался портировать, но не получилось и бросил Жду код. |
Автор: | kuntashov [ 31 окт 2011, 21:01 ] |
Заголовок сообщения: | Re: Исключения (exceptions) и их отлов в скриптах |
artbear писал(а): А я в свое время пару часов попытался портировать, но не получилось и бросил Жду код. Как падучесть поборю, закоммичу. Сейчас очень часто падает, потому что до конца не отладил еще: на одном духу без единого запуска настрочил код, а потом стал запускать и последовательно исправлять ошибки. Сейчас запускается, но почему-то регулярно в произвольные моменты падает. Но ничего, мы его обуздаем |
Автор: | kuntashov [ 31 окт 2011, 21:03 ] |
Заголовок сообщения: | Re: Исключения (exceptions) и их отлов в скриптах |
Александру: покопался и инете, ничего путного не нашел, единственное, что теоретически может пригодиться (если дело все-таки во внутренностях Снегопата): http://stackoverflow.com/questions/3145 ... atchinvoke |
Автор: | artbear [ 01 ноя 2011, 07:24 ] |
Заголовок сообщения: | Re: Исключения (exceptions) и их отлов в скриптах |
kuntashov писал(а): Как падучесть поборю, закоммичу. Выложил бы здесь, поиграться ЗЫ перед тестированием не могу устоять |
Автор: | kuntashov [ 06 ноя 2011, 22:48 ] |
Заголовок сообщения: | Re: Исключения (exceptions) и их отлов в скриптах |
Нашел обход проблемы с перехватом исключений. Не очень красивый, конечно, но зато работает. Для решения проблемы мы в скрипт lib.js добавляем возможность подписки на возникающие исключения следующим образом (в дополнение к коду, цитируемому в топикстартере): Код: function SetErrorHandler(errorHandler) { ErrorHandler = errorHandler; } function throwError(e) { if (ErrorHandler) { ErrorHandler.call(null, e); //ErrorHandler(e); return e; } throw e; } И везде в коде, где раньше использовался оператор throw e заменяем его на вызов throwError(e): Код: function macrosThrowErrorMacros() { throw "Excepiton from testExceptionsLib.throwErrorMacros()"; } А в app.js мы подписываемся на исключения следующим образом: Код: var lib = addins.byUniqueName("testExceptionsLib"); lib.object.SetErrorHandler(function(e) { throw e}); Все, теперь явно брошенные в lib.js исключения будут ловиться при помощи конструкции try{}catch(e){} без проблем. |
Автор: | kuntashov [ 06 ноя 2011, 22:56 ] |
Заголовок сообщения: | Re: Исключения (exceptions) и их отлов в скриптах |
artbear писал(а): Выложил бы здесь, поиграться ЗЫ перед тестированием не могу устоять Выкладываю поиграться в бранч jsunit-port. Единственное, она требует версии метода require() с моими последними правками (сделал, чтобы require() работал также, как $addin). Вот его код: Код: // Загрузить скрипт-библиотеку по имени файла или полному пути. // Возвращает объект, предоставляющий доступ ко всем публичным // функциям и переменным скрипта filename, аналогично директиве $addin. function require(filename) { var fullPath = filename; /* Задан полный путь или уникальное имя скрипта? * Проверяем по наличию указания буквы диска в начале пути * или двойного слеша (при адресации скрипта на сетевом ресурсе). */ var isFullPath = fullPath.match(/^(\w\:|\\\\)/); /* Если задано только имя файла, то ищем скрипт-библиотеку по имени файла * в каталоге Scripts\Libs каталога Снегопата. * TODO: Нужен ли "правильный" алгоритм поиска библиотеки, в рабочем каталоге * и в путях, прописанных в переменной среды PATH? */ if (!isFullPath) { var mainFolder = profileRoot.getValue("Snegopat/MainFolder"); var f = v8New("Файл", mainFolder + "scripts\\Libs\\" + filename); if (!f.Существует() || !f.ЭтоФайл()) throw "require: Не найден скрипт " + filename; fullPath = f.ПолноеИмя; } /* Формируем полный путь загрузки скрипта, * включающий в себя протокол. */ var fullLoadString = "script:" + fullPath; /* Проверяем, не загружен ли скрипт уже (по полному пути) * и загружаем, если это не так. */ var lib = addins.byFullPath(fullLoadString); if (!lib) { /* Среди групп аддинов первого уровня ищем группу для * скриптов-библиотек. Если такой группы нет, то создадим ее. */ var libGroupName = "Подгружаемые библиотеки"; var libGroup = addins.root.child; var libFound = false; while (libGroup) { if (libGroup.name == libGroupName) { libFound = true; break } libGroup = libGroup.next; } if (!libFound) libGroup = addins.root.addGroup(libGroupName); // Загружаем скрипт. try { lib = addins.loadAddin(fullLoadString, libGroup); } catch(e) { Message("require: Скрипт-библиотека не загружен: " + fullPath); // Пробрасываем исключение наверх. throw e; } } // require() должен вести себя как и деректива $addin return lib.object; } Пример теста в Tests/Automated. Пока работает только "Запустить все тесты". Что не работает и надо сделать в первую очередь: 1. assign'ы для 1Совских объектов (теперь благодаря to1CValue это реально). 2. нормальный трейсинг (сейчас сделаны заглушки, надо бы вообще общий скрипт-библиотеку Tracer сделать) 3. прогресс-бар 4. примеры, документация, как пользоваться |
Автор: | artbear [ 07 ноя 2011, 07:56 ] |
Заголовок сообщения: | Re: Исключения (exceptions) и их отлов в скриптах |
kuntashov писал(а): Выкладываю поиграться в бранч jsunit-port. Что не работает и надо сделать в первую очередь: 1. assign'ы для 1Совских объектов (теперь благодаря to1CValue это реально). 2. нормальный трейсинг (сейчас сделаны заглушки, надо бы вообще общий скрипт-библиотеку Tracer сделать) Расшифруй по 1 и 2. ассигны и трейсинг - это что? |
Автор: | kuntashov [ 07 ноя 2011, 08:32 ] |
Заголовок сообщения: | Re: Исключения (exceptions) и их отлов в скриптах |
1. Прошу прощения, assert, конечно же, опечатался, да еще и в русской транскрипции )) сейчас методы работают для js-объектов, нужны методы assertValueTable (для таблицы значений), assert1CArray (для массива 1С), assertValueList, assertMap (для соответствия), assertStructure (для структуры) и т.п. 2. Трейсинг: вывод подробной информации о возникающих исключениях. jsUnitCore собирает достаточно подробную инфу об исключениях, включая стек вызовов, их надо бы выводить в случае возникновения ошибок. Сейчас трассировка выводится в окно сообщений без подробностей. В идеале хотелось бы выводить сообщения об ошибках в свое окно (например, в поле табличного документа или в поле хтмл), с раскраской сообщений, с возможностью добавления гиперссылок (чтобы по клику на ошибке открывать в редакторе скрипт, в котором возникла ошибка) и т.п. |
Автор: | artbear [ 07 ноя 2011, 08:45 ] |
Заголовок сообщения: | Re: Исключения (exceptions) и их отлов в скриптах |
kuntashov писал(а): Выкладываю поиграться в бранч jsunit-port. Единственное, она требует версии метода require() с моими последними правками (сделал, чтобы require() работал также, как $addin). Вот его код: Пример теста в Tests/Automated. Пока работает только "Запустить все тесты". Если отдельно загружать и тестировать каталоги Tests/Automated и Tests/Exceptions, то тесты проходят, но если загружать весь каталог Tests, то при тестировании через "Запустить все тесты" выдаются ошибки Цитата: 'constructor' - есть null или не является объектом и выдается окно ошибки Если далее нажать "Пропустить отладку", то в окне сообщений все-таки появляется Цитата: Тест testExampleTestCase::TestSuccessfulTest выполнен успешно Тест testExampleTestCase::TestFailedTest провалился (assertion failed) ЗЫ исправление для require сделано. |
Страница 1 из 4 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |