CodeNebula
Go🔧Core Languagebeginner

Panic and Recover

Go · Core Language · Run with go run

Explanation

`panic` stops normal execution and begins unwinding the stack, running deferred functions along the way. `recover`, called inside a deferred function, stops the unwinding and returns the panic value — letting a program regain control. Go's convention is to use errors for expected failures and reserve `panic` for truly unrecoverable situations (programmer bugs, impossible states).

Real-World Scenario

An HTTP server wraps each request handler in a deferred `recover`. If a handler panics (e.g. a nil-pointer dereference), `recover` catches it, logs the stack, and returns a 500 response — one bad request doesn't crash the whole server.

Quick Snippet

snippet.go
func safeDivide(a, b int) (result int, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("recovered: %v", r)
        }
    }()
    result = a / b // panics if b == 0
    return result, nil
}

r, err := safeDivide(10, 0)
fmt.Println(r, err) // 0 recovered: runtime error: integer divide by zero

Full Example

panic_recover.go
// Compile: go run panic_recover.go
// Output:
//   10 / 2 = 5, err=<nil>
//   10 / 0 = 0, err=recovered: runtime error: integer divide by zero
//   program continues normally
package main

import "fmt"

func safeDivide(a, b int) (result int, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("recovered: %v", r)
		}
	}()
	result = a / b // panics when b == 0
	return result, nil
}

func main() {
	r1, err1 := safeDivide(10, 2)
	fmt.Printf("10 / 2 = %d, err=%v\n", r1, err1)

	r2, err2 := safeDivide(10, 0)
	fmt.Printf("10 / 0 = %d, err=%v\n", r2, err2)

	fmt.Println("program continues normally")
}
Run command
go run panic_recover.go