'''`[http://tcl.tk/man/tcl/TclCmd/error.htm%|%error]`''', a [Tcl commands%|%built-in] [Tcl] [command], triggers an error state.
** See Also**
[An error experiment], by [RS]: A quick hack to implement restarts.
[errorCode]:
[errorInfo]:
[catch]:
[documenting Tcl's warning/error messages]: Useful when you're looking to figure out what went wrong. Incomplete and subject to change at short notice, but something is better than nothing. :-)
[try]:
[throw]:
[return]:
** Synopsis **
: '''`error`''' ''`message`'' ?''`info`''? ?''`code`''?
** Description **
Generates an error with the specified ''message''. If supplied, ''info'' is used to seed the [errorInfo] value, and ''code'' becomes the [errorCode], which is otherwise is `NONE`.
`error` is short for `[return] -level 0 -code error`, which is not the same as
`[return] -code error`, the latter being the equivalent of `[return] -level 1-code error`. With the `-level 0` variant, `-errorinfo` contains the line
number that `return` was called at, whereas with the `level 1` variant,
`errorinfo` contains the line number in the caller that the current routine was
called at. When in doubt, just use `error`.
<<discussion>>----
[DKF]: I find that it is best to use '''error''' (or '''[throw]''') when it is an internal problem of the code, and '''[return] -code error''' when it is a problem caused by the caller like passing in a name when a number was specifically requested for the argument. The problem in that case is that the caller isn't obeying the interface contract, not that the implementation has gone wrong.
----
[RS] 2001-11-21: In [C], errors are something you loathe and try to avoid. In Tcl, they're like "little friends" - helpful (explaining the problem), not messing up everything (as a Segmentation Fault/Bus Error/Divide by Zero would do). For instance,
======
set fp [open foo.bar]
======
leads to the error
======
couldn't open "foo.bar": no such file or directory
======
which tells it pretty well, and does not terminate the application if it has an [event loop] or is [Interactive Tcl]. In C, you would have received a `NULL` pointer, and without checking that, Segmentation Fault would be right around the corner. So in C, you have to add checks for everything that might go wrong; in Tcl, you only need to treat errors if you can express it better than Tcl already does.
And you can also play with errors: to fully break out of a multiply nested loop, put a [catch] outside and a ''throw'' within:
======
catch {
...# deep nesting ...
throw
}
======
There is no ''[throw]'' command in Tcl [[''editors note: Of course there is one nowadays'']], so it is handled by [unknown], which tries to load it from [auto_index], and if that fails too, an error is raised - which in turn is caught by the `[catch]`. Pretty natural, no? And still somehow Zen buddhistic, if you deliberately use a non-existing command, and it does just the right thing... ([Kevin Kenny] introduced this trick in [Tricky catch]).
In some cases, stack traces look better (one less layer) if you replace
======
error {Something went wrong}
======
with
======
return -code error {Something went wrong}
======<<discussion>>
** See also**
[An error experiment], by [RS]: A quick hack to implement restarts.
[errorCode]:
[errorInfo]:
[catch]:
[documenting Tcl's warning/error messages]: Useful when you're looking to figure out what went wrong. Incomplete and subject to change at short notice, but something is better than nothing. :-)
[try]:
[throw]:
[return]:
<<categories>> Arts and crafts of Tcl-Tk programming | Command