It seems the current proposal for error handling will lead to poor practice in error handling.
There are 3 ways errors are usually handled:
if err != nil { return err }
if err != nil { log.Printf("failed to x: %+v", err) return err }
if err != nil { return errors.Wrapf(err, "failed to x: ")}
The check err
and handle err
approch takes care of the first approch but fails to address 2 and 3 because there is no means to add detail to the error. This means if you have an error that's handled from the new approch in a long function, there is no way to know which check caused the error. So, the error less detailed and the code is harder to debug.
One way to address this is to add more parameters to check
and handle
.
func example() error {
handle (err error, annotation string) {
return errors.Wrapf(err, "failed to %s")
}
x,y,err := open("file.txt")
check(err, "open")
// work
check(doSomething(x,y), "doSomething")
// work
...
return nil
}
Or some variation of this. Perhaps, it can be handle(err, annotation... string)
. Then the check could be check(err, format, args)
.
In a funny way, the "Error handling" proposal is encouraging programmers to not use the "Error values" proposal.
So another approch could be
type errorType interface {
WithError(err error)
}
func example() error {
handle (err error, errType errorType) {
return errorType.WithError(err)
}
x,y,err := open("file.txt")
check(err, IOError{})
// work
check(doSomething(x,y), DoSomethingError{X:x, Y:y})
// work
...
return nil
}
This approch would better encourage the use of "Error values".
I don't know what the parameters should be. The golang community can decide what the parameters should be or if it should be a generic. handle<error,T>
? The point is to allow more than one paremeter for better handling.
Again, the core of what I'm trying to point out is the inherant suggestion of not adding details to error handling if check
and handle
only have error as the paramter.
Define var annotation string before the handler and set it before the checks.