Go was designed from the beginning around explicit error returns rather than exceptions. This allows for predictable code development and avoids the hidden traps associated with try/catch constructs in other languages (e.g., Java or C++). An error in Go is an interface that implements the Error() method, allowing for the creation of both simple and composite/wrapped errors with context.
Problems arise from improper error handling (e.g., if they are ignored via _ or not wrapped with additional debugging information) or creating "magic" errors that do not conform to the error interface. It is also important to return errors from public functions and check them in every call.
The solution is to use standard approaches:
Code example:
import ( "errors" "fmt" ) type NotFoundError struct { Resource string } func (e *NotFoundError) Error() string { return fmt.Sprintf("%s not found", e.Resource) } func GetUser(id int) (string, error) { if id != 1 { return "", &NotFoundError{"User"} } return "Steve", nil } func main() { user, err := GetUser(2) if err != nil { if nfe, ok := err.(*NotFoundError); ok { fmt.Println(nfe.Resource, "problem") } else { fmt.Println("error:", err) } } fmt.Println("user:", user) }
Key features:
Can you compare errors using == when handling them, or should you use special methods?
It is better to always use errors.Is() for comparison with wrapped errors; otherwise, comparison via == may not work when errors are wrapped.
if errors.Is(err, os.ErrNotExist) { // handling file not found }
Is it mandatory to implement a struct type for a custom error, or is it sufficient to use errors.New("...")?
If you only need the error text, errors.New() is sufficient. If preserving context (e.g., resource name) is important, it is better to define a struct with the Error() method.
How should you return an error in the case of a successful function execution?
In the case of success, always return a nil error.
return result, nil
Negative Case
A developer writes a function returning an error without explanations (just errors.New("fail")). When analyzing logs, it is impossible to determine the cause.
Pros:
Cons:
Positive Case
A developer defines a custom error type NotFoundError and returns it with detailed description.
Pros:
Cons: