BudiBadu Logo

Samplebadu

Code with Example
BudiBadu Logo
Samplebadu

Go by Example: Error Handling

Go 1.23

Learn idiomatic Error Handling in Go. Unlike exception-based languages, Go treats errors as values. This example demonstrates the standard pattern of returning `(result, error)`, checking for non-nil errors, and defining custom error types for richer context.

Code

package main

import (
    "errors"
    "fmt"
)

// By convention, errors are the last return value and have type error, a built-in interface.
func f1(arg int) (int, error) {
    if arg == 42 {
        // errors.New constructs a basic error value with the given error message.
        return -1, errors.New("can't work with 42")
    }
    // A nil value in the error position indicates that there was no error.
    return arg + 3, nil
}

// Custom error type
type argError struct {
    arg  int
    prob string
}

func (e *argError) Error() string {
    return fmt.Sprintf("%d - %s", e.arg, e.prob)
}

func f2(arg int) (int, error) {
    if arg == 42 {
        // Return custom error
        return -1, &argError{arg, "can't work with it"}
    }
    return arg + 3, nil
}

func main() {
    // Basic error handling
    for _, i := range []int{7, 42} {
        if r, e := f1(i); e != nil {
            fmt.Println("f1 failed:", e)
        } else {
            fmt.Println("f1 worked:", r)
        }
    }

    // Using custom error data
    _, e := f2(42)
    if ae, ok := e.(*argError); ok {
        fmt.Println(ae.arg)
        fmt.Println(ae.prob)
    }
}

Explanation

In Go, it's idiomatic to communicate errors via an explicit, separate return value. This contrasts with the exceptions used in languages like Java and Ruby and the overloaded single result / error value sometimes used in C.

Go's approach makes it easy to see which functions return errors and to handle them using the same language constructs employed for any other, non-error tasks. The error type is a built-in interface. A nil error denotes success; a non-nil error denotes failure.

Benefits of explicit error handling:

  • Control flow is visible and explicit
  • No hidden control paths (like uncaught exceptions)
  • Errors are values that can be programmed with
  • Encourages handling errors where they occur

Code Breakdown

9
Function signature returning (int, error). This is the standard pattern: result first, error last.
12
Creating a simple error using errors.New(). This returns an error value that can be passed up the stack.
19-22
Defining a custom error struct. This allows you to include structured data (like the argument that caused the error) along with the error message.
39
The standard "if err != nil" pattern (compact form). We call the function, assign the results, and check the error in one line.
48
Type assertion e.(*argError) checks if the error is of a specific type. This allows accessing the custom fields (arg, prob) of the custom error struct.