Как действительно перехватить все ошибки с помощью $ etrap в Intersystems Caché? - PullRequest
1 голос
/ 14 октября 2008

Из-за этого я много бился головой. В том, как задумывался $ etrap (специальная переменная обработки ошибок), вы должны быть осторожны, чтобы действительно перехватить все ошибки. Я был частично успешным в этом. Но я все еще что-то упускаю, потому что при запуске в пользовательском режиме (режиме приложения) возникают внутренняя библиотека Cache ошибок, которые все еще останавливают приложение.

То, что я сделал, было:

ProcessX(var)

    set sc=$$ProcessXProtected(var)
    w !,"after routine call"
    quit sc

ProcessXProtected(var)

    new $etrap
    ;This stops Cache from processing the error before this context. Code
    ; will resume at the line [w !,"after routine call"] above
    set $etrap="set $ECODE = """" quit:$quit 0 quit"

    set sc=1 
    set sc=$$ProcessHelper(var)
    quit sc

ProcessHelper(var)

    new $etrap
    ; this code tells Cache to keep unwindind error handling context up
    ; to the previous error handling.
    set $etrap="quit:$quit 0 quit"

    do AnyStuff^Anyplace(var)

    quit 1

AnyStuffFoo(var)
    ; Call anything, which might in turn call many sub routines
    ; The important point is that we don't know how many contexts
    ; will be created from now on. So we must trap all errors, in any
    ; case.

    ;Call internal Cache library
    quit

После всего этого я вижу, что когда я вызываю программу из командной строки, она работает! Но когда я звоню из Cache Terminal Script (как мне сказали, в режиме приложения), происходит сбой и прерывается работа программы (механизм перехвата ошибок не работает должным образом).

1 Ответ

1 голос
/ 20 октября 2008

Возможно ли, что ловушка ошибок старого стиля ($ ZTRAP) устанавливается только в пользовательском режиме?

Документация по этому вопросу довольно хорошая, поэтому я не буду повторять все это здесь, но ключевой момент заключается в том, что $ ZTRAP не является Ново-ed таким же образом, как $ ETRAP. В некотором смысле, он «неявно новый», так как его значение относится только к текущему уровню стека и последующим вызовам. Он возвращается к любому предыдущему значению, как только вы выйдете за уровень, на котором он был установлен.

Кроме того, я не уверен, существует ли определенный порядок приоритета между обработчиками $ ETRAP и $ ZTRAP, но если $ ZTRAP имеет более высокий приоритет, это переопределит ваши $ ETRAP.

Вы можете попробовать установить $ ZTRAP непосредственно перед вызовом функции библиотеки. Установите для него значение, отличное от $ ETRAP, чтобы вы могли быть уверены, какой из них был запущен.

Даже это может не помочь, хотя. Если в библиотечной функции установлена ​​переменная $ ZTRAP, новое значение вступит в силу, поэтому это не будет иметь значения. Это поможет вам только в том случае, если значение $ ZTRAP пришло откуда-то вверх по стеку.

Вы не упомянули, какая функция библиотеки вызвала это. В моей компании есть исходный код для некоторых библиотечных функций, поэтому, если вы скажете мне имя функции, я посмотрю, что я могу найти. Пожалуйста, дайте мне также значение $ ZVersion, чтобы я мог быть уверен, что мы говорим об одной и той же версии Cache.

...