Можете ли вы показать, как вы ловите / помещаете информацию в неинтерактивном режиме?
Если вы сделали
if {[catch {...your...code...here...} err]} {
puts "Error info $err"
}
Тогда описанное вами поведение ожидается - $err
имеет только"краткая информация".Вместо этого вам может потребоваться puts
:
puts "Error info $err\nFull info: $::errorInfo"
Префикс ::
необходим в случае, если ваш catch вызывается внутри proc или пространства имен, чтобы убедиться, что используемая переменная является фактическим toplevel:: errorInfo.
Отредактировано для решения вопроса
Когда Колин ответил , трассировки стека, найденные в ваших test1
и test2
, отличаютсяиз-за того, где вы разместили улов.Позвольте мне проиллюстрировать.Вот несколько цепочек Tcl-процессов:
proc one {} {
two
}
proc two {} {
three
}
proc three {} {
four
}
proc four {} {
error "Yup, an error"
}
Если вы оцените
catch {four}
puts $::errorInfo
Вы просто получите трассировку стека, которая выглядит следующим образом:
Yup, an error
while executing
"error "Yup, an error""
(procedure "four" line 2)
invoked from within
"four"
Thisэто потому, что трассировка стека между тем, где произошла ошибка (внутри four
), и тем местом, где вы ее уловили, вызывает только один вызов процедуры.
Если вместо этого вы поймали ошибку «еще дальше», например:*
catch {one}
puts $::errorInfo
Трассировка стека между оператором catch
и ошибкой включает в себя процедуры one
, two
, three
и four
.Это приводит к трассировке стека примерно так:
Yup, an error
while executing
"error "Yup, an error""
(procedure "four" line 2)
invoked from within
"four"
(procedure "three" line 2)
invoked from within
"three"
(procedure "two" line 2)
invoked from within
"two"
(procedure "one" line 2)
invoked from within
"one"
Итак ... в соответствии с вашим примером для test1
, если вы переопределите three
следующим образом:
proc three {} {
catch {four}
puts $::errorInfo
}
ИВы оценили
if {[catch {one}]} {
puts "Found an error"
}
Вы бы не см. "Обнаружена ошибка", поскольку тело three
обнаружило ошибку и напечатало трассировку стека.Трассировка стека содержит только вызовы между оператором catch
и ошибкой, которая (как и мой первый пример) состоит только из вызова four
.
Итак, где вы размещаете операторы catch
Вопрос.
В связанной заметке вы можете повторно выдать ошибку, сохранив трассировку стека, если вы того пожелаете.Вот новое определение для three
:
proc three {} {
if {[catch {four} err]} {
puts "Caught an error $err, re-throwing"
error $err $::errorInfo
}
}
Теперь, с повторно выданной ошибкой, вы увидите это:
tchsh% catch {one}
Caught an error Yup, an error, re-throwing
1
tclsh% set ::errorInfo
Yup, an error
while executing
"error "Yup, an error""
(procedure "four" line 2)
invoked from within
"four"
(procedure "three" line 2)
invoked from within
"three"
(procedure "two" line 2)
invoked from within
"two"
(procedure "one" line 2)
invoked from within
"one"