Снегопат

Обсуждение Снегопата
Текущее время: 27 апр 2024, 14:15

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу 1, 2, 3, 4  След.
Автор Сообщение
СообщениеДобавлено: 31 окт 2011, 16:00 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:53
Сообщения: 448
Откуда: Саратов
Всем привет!

Достаточно много возился в эти выходные со скриптами на 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'ы бросают исключения).

_________________
С уважением,
Александр Кунташов
Канал про 1С в Телеграме: @kuntashov_devnotes


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 31 окт 2011, 16:25 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:36
Сообщения: 1085
kuntashov писал(а):
В порыве экспериментов я начерно портировал JsUnit (http://jsunit.net) под Снегопат и даже "нарисовал" простейший запускатель тестов, и оно даже работает, за исключением того, что первый же сломавшийся тест останавливает выполнение всех тестов из-за озвученной проблемы (assert'ы бросают исключения).

А я в свое время пару часов попытался портировать, но не получилось и бросил :)
Жду код.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 31 окт 2011, 21:01 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:53
Сообщения: 448
Откуда: Саратов
artbear писал(а):
А я в свое время пару часов попытался портировать, но не получилось и бросил :)
Жду код.


Как падучесть поборю, закоммичу. Сейчас очень часто падает, потому что до конца не отладил еще: на одном духу без единого запуска настрочил код, а потом стал запускать и последовательно исправлять ошибки.

Сейчас запускается, но почему-то регулярно в произвольные моменты падает. Но ничего, мы его обуздаем :)

_________________
С уважением,
Александр Кунташов
Канал про 1С в Телеграме: @kuntashov_devnotes


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 31 окт 2011, 21:03 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:53
Сообщения: 448
Откуда: Саратов
Александру: покопался и инете, ничего путного не нашел, единственное, что теоретически может пригодиться (если дело все-таки во внутренностях Снегопата):

http://stackoverflow.com/questions/3145 ... atchinvoke

_________________
С уважением,
Александр Кунташов
Канал про 1С в Телеграме: @kuntashov_devnotes


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 01 ноя 2011, 07:24 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:36
Сообщения: 1085
kuntashov писал(а):
Как падучесть поборю, закоммичу.

Выложил бы здесь, поиграться :)
ЗЫ перед тестированием не могу устоять :)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 06 ноя 2011, 22:48 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:53
Сообщения: 448
Откуда: Саратов
Нашел обход проблемы с перехватом исключений.
Не очень красивый, конечно, но зато работает.

Для решения проблемы мы в скрипт 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){} без проблем.

_________________
С уважением,
Александр Кунташов
Канал про 1С в Телеграме: @kuntashov_devnotes


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 06 ноя 2011, 22:56 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:53
Сообщения: 448
Откуда: Саратов
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. примеры, документация, как пользоваться

_________________
С уважением,
Александр Кунташов
Канал про 1С в Телеграме: @kuntashov_devnotes


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 ноя 2011, 07:56 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:36
Сообщения: 1085
kuntashov писал(а):
Выкладываю поиграться в бранч jsunit-port.

Что не работает и надо сделать в первую очередь:

1. assign'ы для 1Совских объектов (теперь благодаря to1CValue это реально).
2. нормальный трейсинг (сейчас сделаны заглушки, надо бы вообще общий скрипт-библиотеку Tracer сделать)

Расшифруй по 1 и 2.
ассигны и трейсинг - это что?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 ноя 2011, 08:32 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:53
Сообщения: 448
Откуда: Саратов
1. Прошу прощения, assert, конечно же, опечатался, да еще и в русской транскрипции )) сейчас методы работают для js-объектов, нужны методы assertValueTable (для таблицы значений), assert1CArray (для массива 1С), assertValueList, assertMap (для соответствия), assertStructure (для структуры) и т.п.

2. Трейсинг: вывод подробной информации о возникающих исключениях. jsUnitCore собирает достаточно подробную инфу об исключениях, включая стек вызовов, их надо бы выводить в случае возникновения ошибок.
Сейчас трассировка выводится в окно сообщений без подробностей. В идеале хотелось бы выводить сообщения об ошибках в свое окно (например, в поле табличного документа или в поле хтмл), с раскраской сообщений, с возможностью добавления гиперссылок (чтобы по клику на ошибке открывать в редакторе скрипт, в котором возникла ошибка) и т.п.

_________________
С уважением,
Александр Кунташов
Канал про 1С в Телеграме: @kuntashov_devnotes


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 ноя 2011, 08:45 
Не в сети
Аватара пользователя

Зарегистрирован: 24 авг 2011, 15:36
Сообщения: 1085
kuntashov писал(а):
Выкладываю поиграться в бранч jsunit-port.

Единственное, она требует версии метода require() с моими последними правками (сделал, чтобы require() работал также, как $addin). Вот его код:

Пример теста в Tests/Automated.
Пока работает только "Запустить все тесты".

Если отдельно загружать и тестировать каталоги Tests/Automated и Tests/Exceptions, то тесты проходят,
но если загружать весь каталог Tests, то при тестировании через "Запустить все тесты" выдаются ошибки
Цитата:
'constructor' - есть null или не является объектом

и выдается окно ошибки
Если далее нажать "Пропустить отладку", то в окне сообщений все-таки появляется
Цитата:
Тест testExampleTestCase::TestSuccessfulTest выполнен успешно
Тест testExampleTestCase::TestFailedTest провалился (assertion failed)

ЗЫ исправление для require сделано.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу 1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB