'''`[http://www.tcl.tk/man/tcl/TclCmd/try.htm%|%try]`''', a [Tcl Commands%|%built-in] Tcl [command], evaluates a script, [eval%|%evaluates] additionally scripts depending on the resulting [return%|%return code], and then optionally evaluates a final script. [http://tip.tcl.tk/329%|%TIP #329] added '''try''' to Tcl 8.6. The [tcllib] module [https://core.tcl.tk/tcllib/doc/trunk/embedded/www/tcllib/files/modules/try/tcllib_try.html%|%try] provides a forward-compatibility implementation of TIP 329 for Tcl 8.5. ** Synopsis ** : '''try''' ''body'' ?''handler ...''? ?'''finally''' ''script''? ** Documentation ** [http://www.tcl.tk/man/tcl/TclCmd/try.htm%|%official reference]: ** Description ** Each ''handler'' specifies a [return%|%return code] or an '''`[return%|%-errorcode]`''' value, a response script, and a set of variable names that the response script can use to access the return details. An arbitray number of handlers may be specified, and there are currently two types of handler defined: '''on''' ''code variableList script'': ''code'' matches an integer [return%|%returned] in the `-code` option, and may also be expressed as one of the following literal words: '''ok''', '''error''', '''return''', '''break''', or '''continue''', which correspond to the integers 0 through 4 respectively. '''trap''' ''errorPrefixList variableList script'': ''errorPrefixList'' is a list of values to be exactly compared against the same number of values in the [return%|%returned] '''`-errorcode`'''. ''variableList'' contains either zero, one or two variable names. The first contains the returned result, and the second contains the [return%|%return options]. If present, the '''finally''' clause's ''script'' will be evaluated after the evaluation of the ''body'' and whichever ''handler'' was selected. It will be evaluated even if the ''body'' or the ''handler'' produce an error. It will ''not'' be evaluated if the interpreter is deleted in the ''body'' or ''handler''. ** Examples ** [do...until in Tcl]: contains a nice example by [dkf] of using `try` in a [New Control Structures%|%new control structure]. This first example is from the manual page for try, and demonstrates testing for two different error conditions which might arise when attempting to `[open]` a file. ====== try { set f [open /some/file/name] } trap {POSIX EISDIR} {} { puts {failed to open /some/file/name: it's a directory} } trap {POSIX ENOENT} {} { puts {failed to open /some/file/name: it doesn't exist} } ====== [AMG]: Here's an example of reraising an error: ====== try { set f [open /some/file/name] } on error {result options} { puts {something broke!} return -options $options $result } ====== ** Use as a Shim ** [AMG]: [[try]] can be used to supply a full script where a single command (see [[command prefix]]) is expected. Simply give it a single argument, that being the entire script to run. This is a more straightforward alternative to [[[apply]]]. It will not produce a new stack frame, so it can directly access local variables with no need for [[[upvar]]]. [[[eval]]] is the same way but slower. [[try]] is [bytecode]-compiled. [Philip Smolen]: Example: `coroutine x try {yield 3; yield 7; yield 23}` [Philip Smolen]: Example: coroutine x try {yield 3;yield 7; yield 23} [AMG]: Building on the above technique, the combination of [[[tailcall]]] and [[try]] can be used in place of [[[uplevel] 1]] when the [[uplevel]] is the final command of a [proc] or [apply] body. [[uplevel]] only provides access to the caller's variables, whereas [[tailcall]] actually makes the caller do something, e.g. [[[return]]]. As mentioned above, the [[try]] in there is a shim to make [[tailcall]] run a script rather than a single command. ** See Also ** [throw]: [catch]: [error]: [return]: [Forward-compatible try and throw]: