Немедленно нажми на RESET, All!
Вот, допустим существует некая абстрактная package. Которая пытается
создавать некие объекты в tcl со временем жизни "до конца процедуры".
Делается это просто: объект связывается с переменной, не важно как,
а на последнюю ставится trace unset. Здорово придумано, да?
А вот теперь предположим, что существует другая не менее абстрактная
package, которая чего-то там делает, и для чего имеет выражения вида
"if {[catch {blablabla...}} {blablabla...}". И, соответственно, обрабатывает
как и положено возникающие ошибки.
А теперь представьте, что в программе где-то возникает исключение (ошибка).
Она тоже корректно очень обрабатывается:
if {[catch {
blablabla...
} message]} {
switch $::errorCode {
some-special-code {...}
default {
error $message $::errorInfo $::errorCode
}
}
Надеюсь понятен смысл: выловить свои исключения и отдать дальше остальные.
Проблема в "отдать дальше": в момент самоликвидации процедуры, со временем
жизни связан некий объект, самоунитожающийся посредством trace unset,
в его "деструкторе" в коде второго package тоже что-то там через catch
ловится... Надеюсь понятно, что в этот момент errorCode обрабатываемого
в настоящий момент исключения перестаёт существовать? Со всеми вытекающими
последствиями -- возникает чёрт знает какая ошибка.
Нет проблема в целом понятная -- исключение в исключении. То ли надо
стек из errorCode делать, то ли не доводить до такого. Но как не доводить?
trace конечно нехорошо, через него тааакого можно накрутить... Но он
есть и от него никуда не избавиться. И catch во втором package -- тоже
имеет полное право быть. А что он из trace вызывается -- откуда ему знать?
Можно пропатчить второй package -- а именно Snit, чтобы он сохранял
что ли errorCode и т.п., именно на такой случай. Но как быть в общем случае?
Используешь catch -- обязательно сохраняй errorCode? Как-то очень нехорошо
получается. Ведь формально -- нигде никакой ошибки нет. Или в функции вызываемой trace сохранять обязательно. Тоже некрасиво. :-/