Return nil or custom error in Go
Don't use DetailedError
as a return type, always use error
:
func foo(answer, x, y int) (int, error) {
if answer == 42 {
return 100, nil //!! cannot use nil as type DetailedError in return argument
}
return 0, DetailedError{x: x, y: y}
}
The fact that your DetailedError
type satisfies the error
interface is sufficient to make this work. Then, in your caller, if you care about the extra fields, use a type assertion:
value, err := foo(...)
if err != nil {
if detailedErr, ok := err.(DetailedError); ok {
// Do something with the detailed error values
} else {
// It's some other error type, behave accordingly
}
}
Reasons for not returning DetailedError
:
It may not appear to matter right now, but in the future your code may expand to include additional error checks:
func foo(answer, x, y int) (int, error) {
cache, err := fetchFromCache(answer, x, y)
if err != nil {
return 0, fmt.Errorf("Failed to read cache: %s", err)
}
// ...
}
The additional error types won't be of DetailedError
type, so you then must return error
.
Further, your method may be used by other callers that don't know or care about the DetailedError
type:
func fooWrapper(answer, x, y int) (int, error) {
// Do something before calling foo
result, err := foo(answer, x, y)
if err != nil {
return 0, err
}
// Do something after calling foo
return result, nil
}
It's unreasonable to expect every caller of a function to understand a custom error type--this is precisely why interfaces, and in particular the error
interface, exists in Go.
Take advantage of this, don't circumvent it.
Even if your code never changes, having a new custom error type for every function or use-case is unsustainable, and makes your code unreadable and impossible to reason about.
DetailedError struct
zero value isn't nil
but DetailedError{}
. You can either return error
interface instead of DetailedError
func foo(answer, x, y int) (int, error) {
or use pointer
func foo(answer, x, y int) (int, *DetailedError) {
...
//and
func (e *DetailedError) Error() string {