Contents

Error Handling

Syntax

In Go, errors are represented by the built-in error type, which is an interface with a single method Error() string. The error type is used to indicate an unexpected state or failure in a program. Go functions that may fail typically return an error as their last return value. If an error occurs, it can be checked and handled appropriately. Go’s error handling approach encourages explicit checks and handling, which leads to clear and robust code.

Example:

				
					func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("cannot divide by zero")
    }
    return a / b, nil
}

func main() {
    result, err := divide(4, 0)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Result:", result)
}
				
			

Creating Errors

Errors in Go can be created using the errors.New function from the errors package or using fmt.Errorf to format the error message. You can define custom error types by implementing the error interface, allowing for more descriptive and structured error handling. Custom errors can carry additional context about the failure, which can be useful for debugging and handling specific error cases.

Example:

				
					type CustomError struct {
    Code    int
    Message string
}

func (e *CustomError) Error() string {
    return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
}

func doSomething(flag bool) error {
    if !flag {
        return &CustomError{Code: 404, Message: "Resource not found"}
    }
    return nil
}

func main() {
    err := doSomething(false)
    if err != nil {
        fmt.Println(err)  // Output: Error 404: Resource not found
    }
}
				
			

Panic and Recover

panic is a built-in function in Go that stops the normal execution of the current goroutine and begins panicking. When a function panics, it unwinds the stack, executing any deferred functions before the program crashes. Panics are typically used for unrecoverable errors or conditions that should not happen. recover is another built-in function that regains control of a panicking goroutine. It’s used within deferred functions to handle the panic and prevent the program from crashing, allowing for graceful error handling and recovery.

Example:

				
					func mayPanic() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()
    
    fmt.Println("Starting")
    panic("something went wrong")  // Triggers panic
    fmt.Println("This will not be printed")
}

func main() {
    mayPanic()
    fmt.Println("Program continues")
}

				
			

Defer Statement

The defer statement in Go is used to schedule a function to be executed after the surrounding function completes, regardless of whether it completes normally or due to a panic. Deferred functions are executed in LIFO (Last In, First Out) order. This feature is particularly useful for resource cleanup, such as closing files, unlocking mutexes, or handling any necessary finalization tasks.

Example:

				
					func main() {
    fmt.Println("Opening file")
    defer fmt.Println("Closing file")  // This will execute at the end

    fmt.Println("Reading file")
    defer fmt.Println("Done reading")  // This will execute just before closing

    fmt.Println("Processing file")
}