Reputation: 46
I have 2 go functions:
func sampleFunction () {
u, err := findDog(1)
if err != nil {
// We couldn't find the dog, print a message.
fmt.Println(err)
// Custom error types.
if _, ok := err.(*dneError); ok {
fmt.Println("Custom dog dne error for the end-user here.")
}
} else {
// Do something with u.
u.doSomething() // Is this idiomatic in Go?
// Should we explicility check for u != nil?
// Or does the if check above need to return?
// (even if I would like the function to be longer)
}
}
// findDog returns a dog with a given ID. If not found, returns an error.
func findDog(id int) (*models.Dog, error) {
found, err := models.FindDog(id)
// Is this return scheme/flow too brittle?
if err != nil {
return nil, &dneError{fmt.Sprintf("Dog %d does not exist in the" +
"database: %s", id, err.Error())}
}
return found, nil
}
I just want to make sure I'm handling errors and nils correctly, so my 2 main questions are:
In findDog, am I returning nil appropriately in both cases?
In sampleFunction, is it idiomatic to not explicitly check u != nil, or am I just doing this completely incorrectly?
My goal is to properly show errors/problems to the programmers when they need it, and show errors/problems to the users when they need it, while also adhering to idiomatic standards. Thank you for your time.
Upvotes: 2
Views: 4683
Reputation: 6274
Yes, this is idiomatic Go. Because errors are handled up front, an error means something failed and the result is either nil
, or e.g. perhaps a partially written buffer that isn't of any use.
P.S. I also have a suggestion that would make things more idiomatic. The idiom goes something like "Indent error blocks, not code". You specifically have an if/else in your sampleFunction
, yet in most error checking circumstances (not all) you handle it and return, then skip the else and the flow simply continues. Why indent when you don't have to? This has the effect of making even long functions easy to read because the intended flow of the function can be read top-to-bottom and without having to bounce back and forth between if/else blocks. At least in many occasions.
I had a pull request into someone's repository amended because I had an if/else where the if with return was sufficient.
EDIT
So my answer was bothering me a little bit, and now I remember why. It's normally idiomatic for a non nil
error
return to indicate that the other return value(s) are useless, but there are indeed exceptions. Be sure to check individual documentation.
As a concrete example, see bytes.Buffer.ReadBytes
If ReadBytes encounters an error before finding a delimiter, it returns the data read before the error and the error itself (often io.EOF).
Upvotes: 3
Reputation: 749
In my personal opinion you are handling it very well, Just a recommendation as I don't know what models.FindDog(id)
does I would double check found
and if this is nil
return error, summarizing if err != nil || found == nil {
Note: doing this return err.Error()
could fail
Upvotes: 1