» Quick Introduction to Go » 1. Basics » 1.8 Error Handling

Error Handling

Error handling in Go is designed to be explicit and encourages developers to check for errors explicitly rather than relying on exceptions. The basic idea is that functions that might encounter errors return both a result and an error, and the calling code is responsible for checking and handling the error.

Returing Errors

Functions that might encounter errors return a value of type error as the last return type.

func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("cannot divide by zero")
    }
    return a / b, nil
}

You can use errors.New to create a new error, or you can use fmt.Errorf for more complex error messages.

if err := someFunction(); err != nil {
    return fmt.Errorf("error in someFunction: %w", err)
}

Handling Errors

Always check for errors explicitly. You can use an if statement to check for errors.

result, err := divide(10, 0)
if err != nil {
    fmt.Println("Error:", err)
} else {
    fmt.Println("Result:", result)
}

Propagate errors up the call stack by returning them from functions. Each layer can decide how to handle or wrap the error.

func compute() error {
    result, err := divide(10, 0)
    if err != nil {
        return fmt.Errorf("error in compute: %w", err)
    }
    // continue processing
    // ...
}

Panic

The panic function can be used to cause a run-time panic.

func example() {
    panic("serious error that cannot be handled here")
}

Defer

The defer statement can be used to ensure that a function call is performed later in a program's execution, usually for cleanup purposes. This can be useful for handling panics and releasing resources.

file, err := os.Open("example.txt")
if err != nil {
    return err
}
defer file.Close()
// ...

Recover

The recover function is used to regain control of a panicking goroutine.

func example() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()
    
    // some code that might panic
    panic("something went wrong")
}

Custom Errors

You can create custom error types by implementing the error interface.

type MyError struct {
    Msg string
}

func (e *MyError) Error() string {
    return e.Msg
}

This allows you to provide more context and information about the error.

err := &MyError{Msg: "This is a custom error"}

Remember that idiomatic Go code prefers explicit error handling over exceptions, making the code more predictable and readable.

Code Challenge

Write a function ReverseString in Go that takes a string as input and returns its reverse.
However, handle the case where the input string is empty and return a custom error for this scenario.

Loading...
> code result goes here
Prev
Next