Purpose: to discuss the issues of when and how to write exception handling code.
hv 2011-07-15: Here is a short snippet showing how to use the return command with -code error to throw an exception
proc double x { if {![string is integer $x]} { return -code error "double expects an int, not '$x'" } return [expr {$x * 2}] } set x 5 puts "x = $x" puts "2x = [double $x]" set x Hello puts "x = $x" if {[catch {puts "2x = [double $x]"} errmsg]} { puts "Error: $errmsg" }
Output:
x = 5 2x = 10 x = Hello Error: double expects an int, not 'Hello'
PYK 2016-07-11: For some time I was under the misapprehension that return -code error message was the "standard" way to throw an error. It's not. error and throw are the first commands to use for signalling an error. For one thing, error and throw report the line number they were called from. More importantly, return has the more general purpose of communicating information about some level to the interpreter. return can be considered a sort of restricted uplevel that provides a flexible mechanism for expressing various runtime conditions. return is usually considered to mean, "return from the current call", but what it actually means is "return to the interpreter some information about a level, which in the common case is that the interpreter should return from the current evaluation."
DKF: The reason for using return -code error vs error or throw depends on where the error is. If the problem is in your code, use error or throw. If the problem is in your caller (e.g., because they gave you bad arguments) then use return -code error. Simple.