Backend Development 6 min read

Understanding Exception and Error Handling in Go

This article explains how Go handles exceptions and errors using defer, panic, and recover, compares it with try‑catch in other languages, demonstrates the built‑in error interface, custom error types, and provides multiple code examples and analyses of their output.

360 Tech Engineering
360 Tech Engineering
360 Tech Engineering
Understanding Exception and Error Handling in Go

Exception and error handling are crucial for program robustness. While C++, Java, and Python use try‑catch, Go separates exception handling from control flow by using defer , panic , and recover . A panic raises an exception, which can be caught in a deferred function via recover.

Example demonstrating defer and panic:

func main() {
    // immediate function
    defer func() { // defer block 1
        fmt.Println("----调用 defer1 start----")
        if err := recover(); err != nil {
            fmt.Println(err) // prints panic content
        }
        fmt.Println("----调用 defer1 end----")
    }()
    defer func() { // defer block 2
        fmt.Println("----调用 defer2 start----")
        if err := recover(); err != nil {
            fmt.Println(err)
        }
        fmt.Println("----调用 defe2r end----")
    }()
    panic("测试")
}

The execution result shows that defer works like C++ destructors: the last added defer runs first, forming a stack. panic stops normal execution unless recovered.

Go's standard error handling uses the error interface:

type error interface {
    Error() string
}

An implementation errorString provides a simple error type:

// errorString is a trivial implementation of error.
type errorString struct {
    s string
}

func (e *errorString) Error() string { return e.s }

The errors.New function creates an errorString :

// New returns an error that formats as the given text.
func New(text string) error {
    return &errorString{text}
}

Using this, a function can return an error when arguments are missing:

func add(args ...int) (int, error) {
    var sum int
    if len(args) == 0 {
        return 0, errors.New("参数为空")
    }
    for _, arg := range args {
        sum += arg
    }
    return sum, nil
}

Calling the function:

sum, err := add()
if err != nil {
    fmt.Println(err.Error())
} else {
    fmt.Println(sum)
}

Developers can also define custom error types that satisfy the error interface:

type myError struct {
    curFile     string
    code        int
    description string
}

func (e *myError) Error() string { return e.description }

Using the custom error in a function:

func add(args ...int) (int, error) {
    var sum int
    if len(args) == 0 {
        return 0, &myError{curFile: "test.go", code: -1, description: "参数不能为空哦!"}
    }
    for _, arg := range args {
        sum += arg
    }
    return sum, nil
}

Case study 1 illustrates the order of deferred panics:

package main
import "fmt"
func main() { doTest() }
func doTest() {
    defer func() { panic("报错2") }()
    defer func() { panic("报错1") }()
    panic("报错3")
}

Analysis: defer forms a stack, so the panic from the second defer is printed before the first, and the direct panic is printed last.

Case study 2 shows that recover only works inside a deferred function:

package main
import "fmt"
func main() {
    doTest()
    fmt.Println("main捕获到错误:", recover())
}
func doTest() {
    defer func() { fmt.Println("1捕获到错误:", recover()) }()
    fmt.Println("2捕获到错误:", recover())
    panic("报错3")
}

Analysis: The recover call outside a defer returns nil , so the panic propagates, while the deferred recover captures the panic.

The article concludes with a note that the content is reposted from 360 Cloud Computing and invites readers to leave comments.

GoError handlingExceptionpanicdeferrecover
360 Tech Engineering
Written by

360 Tech Engineering

Official tech channel of 360, building the most professional technology aggregation platform for the brand.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.