Errors
An error is declared, given a name and the sentence it should say:
error NotEven = "the number is odd"A function that can fail says so with ! on its result:
error NotEven = "the number is odd"
func half(n i32) !i32 { if n % 2 != 0 { return error.NotEven } return n / 2}An error is a code at run time and nothing more: no payload, no allocation, and
the message lives in the binary rather than being built when something goes
wrong. The set is global to the program, so error.Timeout raised by two
packages is one error and a caller handles it once.
Declaring is not ceremony — it is what makes error.NotEvn a compile error
instead of a second error nobody handles. Several at once, and one without a
message when the name says everything:
error Closed = "the channel is closed"error Refused = "nothing is listening there"error tooDeep // lowercase: nobody outside this packagenameof(e) gives the name and e.Message() the sentence:
half(41) catch |e| { try io.Printf("{}: {}\n", nameof(e), e.Message())}// NotEven: the number is oddtry passes a failure up to your own caller:
func quarter(n i32) !i32 { a := try half(n) return try half(a)}catch handles it. Three shapes:
error NotEven = "the number is odd"
func half(n i32) !i32 { if n % 2 != 0 { return error.NotEven } return n / 2}
func quarter(n i32) !i32 { a := try half(n) return try half(a)}
func main() int { a := quarter(40) catch 0 // a fallback value
b := quarter(41) catch |e| { // inspect it, then leave return int(a) + 2 }
return int(a) + int(b)}and catch {} when you mean to carry on regardless — which is most of what you
write inside a defer.
A handler block that has to produce a value must leave the scope, with a
return, break or continue; there is nowhere for it to get one otherwise.
When the result is being thrown away anyway, as in a statement on its own, it
can just fall out.
You cannot ignore a failure by accident. Calling a fallible function and
throwing the result away is a compile error, and so is reaching into an !T
that has not been handled.
main can be fallible too, in which case an error that reaches it becomes the
exit status.