Tohil Tcl Errors¶
If Python code invoked from Tcl results in a Python exception that is not trapped by any of the Python code, Tohil will trap the exception, translate it into a Tcl error, and propagate the error back through Tcl.
If Tcl is being used interactively and the error isn’t caught, it will make its way to an error reported in the interactive session.
Likewise if the Tcl error propagates all the way back to tohil due to Tcl code having been called from Python, the Tcl error will be propagated as a Python exception, see :ref:_tohil-exceptions.
The Tcl stack trace will include the Python stack trace of the Python code that was executing at the time of the exception being raised.
The Tcl error code, often referred to as the Tcl global errorCode, but also accessible via a Tcl dict created via an argument to Tcl’s catch or try, is made available to Python through Tohil’s TclError object.
Tcl’s errorCode represents additional information about an error in the form of a Tcl list that is intended to be easy easy to process with programs, unlike, for instance, error messages, which may be localized into different languages and be difficult to interpret reliably using a program.
The first element of the errorCode list identifies a general class of errors. For Tcl errors generated by Tohil in response to uncaught Python exceptions, the first element of errorCode is set to PYTHON.
The next element is the Python class name of the exception, followed by the base error message.
>>> tohil.interact()
% tohil::exec missing_function
name 'missing_function' is not defined
while evaluating tohil::exec missing_function
% puts $errorCode
PYTHON NameError {name 'missing_function' is not defined}
% puts $errorInfo
name 'missing_function' is not defined
from python code executed by tohil File "tohil", line 1, in <module>
invoked from within
"tohil::exec missing_function"
("eval" body line 1)
invoked from within
"eval $::tclreadline::LINE"
Here is another sample Tcl session catching an uncaught Python exception as a Tcl error, where the errorCode is set into the catch options variable:
>>> $ tclsh % package require tohil 3.2.0 % catch {tohil::eval "no"} catchResult catchDict 1 % puts $catchResult name 'no' is not defined % puts [dict get $catchDict -errorcode] PYTHON NameError {name 'no' is not defined}% puts $catchDict -code 1 -level 0 -errorstack {INNER {invokeStk1 tohil::eval no} UP 1} -errorcode {PYTHON NameError {name ‘no’ is not defined}} -errorinfo {name ‘no’ is not defined from python code executed by tohil File “tohil”, line 1, in <module> invoked from within “tohil::eval “no””} -errorline 1