catch -- Catch exceptions
Syntax: catch script ?resultVarName? ?optionsVarName?
Executes the script, catching the script's result. The catch command returns an integer
result code, indicating why the script returned. If resultVarName is given, the
named variable in the caller's scope is set to the script's actual return value. If
optionsVarName is given, the named variable is set to the return options
dictionary in the caller's scope.
catch is most often used to catch errors. For example,
if {[catch {do_something} result]} {
puts "Error message: $result"
} else {
puts "Good result: $result"
}
Return Codes
The return value of catch is an integer code that indicates why the script returned. There are
five standard return codes:
| Return Code | Effect |
|---|---|
| 0 (ok) | Normal. The result variable is set to the script's result. |
| 1 (error) | A command in the script threw an error. The result variable is set to the error message. |
| 2 (return) | The script called return. The result variable is set to the returned value. |
| 3 (break) | The script called break. |
| 4 (continue) | The script called continue. |
In addition, the return command allows any integer to be used as a return code; together with
catch, this can be used to implement new control structures.
The errorCode and errorInfo Variables
When catch catches an error (or when an error message is output in the Molt REPL), the
global variable errorCode will be set to the specific error code (see throw)
and the global variable errorInfo will be set to a human-readable stack trace.
The Options Dictionary
The options dictionary saved to the optionsVarName contains complete information about the return options. See return for a complete discussion of what the return options are and how they are used.
Rethrowing an Error
Sometimes it's desirable to catch an error, take some action (e.g., log it), and then rethrow
it. The return command is used to do this:
set code [catch {
# Some command or script that can throw an error
} result opts]
if {$code == 1} {
# Log the error message
puts "Got an error: $result"
# Rethrow the error by returning with exactly the options and return
# result that we received.
return {*}$opts $result
}
Visualizing the Return Protocol
The semantics of the return/catch protocol are tricky. When implementing a new control
structure, or a modified or extended version of return, break, continue, etc., it is
often useful to execute short scripts and examine the options dictionary in the REPL:
% catch { break } result opts
3
% set result
% set opts
-code 3 -level 0
% catch { return "Foo" } result opts
2
% set result
Foo
% set opts
-code 0 -level 1
%
This REPL dialog shows that break yields result code 3 immediately, to be handled by the
calling command (usually a loop), while return returns from the calling procedure (-level 1)
and then yields an ok (i.e., normal) result to its caller.
TCL Liens
Molt's catch command differs from Standard TCL's in the following ways:
-
The options dictionary, as returned, lacks the
-errorlineand-errorstackoptions. These might be added over time. -
All options passed to
return, whether understood by Standard TCL or not, are passed through and included in thecatchoptions dictionary. Molt does not currently support this.
All of the common patterns of use are supported.