Semicolons might help to handle errors like this:
func f2() error {
err := f1(); if err == nil { return nil }
// ...
}
Pros:
- The code is very explicit (that means that every reader will understand what is happening in the code)
- Full control over control flow
- Handle error at the first place
- You can focus on reading function calls
Cons:
- Chattines (the code is chatty comparing to GO2 check keyword)
I would prefer writing more explicit code rather than beautiful code with complex control flow.
How it works: One-liner function call and simple error handling by using semicolon (instead of multiline GO1 multiline error handling)
Pros:
- Simple cases are very readable
Cons:
- control flow is much more complicated (much more like try+catch).
- it would introduce very unique / keywords
- idiom tends NOT to handle errors at first place but rather with some generic handler.
- keep error handling logic close to the function/method call
- allow reader to focus on function calls
- let's not add new keywords if not necessary
- let's keep control flow very simple
Refactor following code snippet (I have borrowed the code snipped from golang/go#27020):
func RetryTemporaryErrors(f func() error) error {
for {
err := f()
if err == nil {
return nil
}
if err, ok := err.(Temporary); !(ok && err.Temporary()) {
return Wrap(err, "not temporary error")
}
err = fiddleThing()
if err != nil {
return err
}
time.Sleep(10 * time.Second)
}
}
to something like this:
func RetryTemporaryErrors(f func() error) error {
for {
err := f(); if err == nil { return nil } //semicolons would work not only for errors
if !TemporaryErr(err) {
return Wrap(err, "not temporary error")
}
err = fiddleThing(); if err != nil { return Wrap(err, "fiddle unsuccessful") }
time.Sleep(10 * time.Second)
}
}
I mean:
if err:= fnc1(); err != nil {
return err
}
Pros:
- Full control over control flow
- Code is explicity
Cons:
- Error handling uglyfies the original code
- Many lines of code are dedicated to error handling
- The with a function call starts in this case with if but I would prefer starting with a function call
I like this! Other than "don't change anything", this is the only proposal I've seen that doesn't look like weird special case magic with 40-80% of the mental overhead of Lisp macros and only 10-20% of their utility (and as someone who once tried turning Go into a Lisp for the sake of syntactic macros, "better error handling" is 25% of how I'd use them!).
Also, it looks like the only change would be in
gofmt
, making this fully backwards compatible with existing code.