codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🐹

Go (Golang)

10 / 72 topics
1Introduction to Go (Golang)2Installation and Setup3Hello World Program4Variables and Constants5Data Types6Operators7Control Structures (if, else, switch)8Functions9Defer Statement10Panic and Recover
Tutorials/Go (Golang)/Panic and Recover
🐹Go (Golang)

Panic and Recover

Updated 2026-04-20
3 min read

Panic and Recover in Go

Introduction

In the world of software development, errors are inevitable. Go, also known as Golang, provides a robust mechanism for handling runtime errors through the use of panic and recover. These mechanisms allow developers to manage unexpected situations gracefully, ensuring that their applications remain stable and reliable.

This tutorial will cover the fundamentals of panic, defer, and recover in Go. We'll explore how these features work together to handle errors effectively, along with best practices for using them in production code.

Understanding Panic

A panic is a built-in function that stops the normal execution flow of a program. When a panic occurs, it unwinds the call stack and executes any deferred functions before terminating the program. This behavior can be useful for handling critical errors that cannot be recovered from within the current context.

Syntax

panic("Something went wrong!")

Example

Let's consider a simple example where we use panic to handle a division by zero error:

package main

import "fmt"

func divide(a, b int) {
    if b == 0 {
        panic("Division by zero is not allowed")
    }
    fmt.Println("Result:", a/b)
}

func main() {
    divide(10, 2) // This will print: Result: 5
    divide(10, 0) // This will cause a panic
}

In this example, the divide function checks if the divisor b is zero. If it is, the function calls panic, which stops the execution and prints the error message.

Understanding Defer

A defer statement schedules a function call to be executed at the end of the surrounding function's execution. It's often used for cleanup activities, such as closing files or releasing resources.

Syntax

defer func() {
    // Cleanup code here
}()

Example

Here's how you can use defer to ensure that a file is closed after its contents are processed:

package main

import (
    "fmt"
    "os"
)

func readFile(filename string) {
    file, err := os.Open(filename)
    if err != nil {
        panic("Failed to open file")
    }
    defer file.Close() // Ensure the file is closed after processing

    // Process the file
    fmt.Println("File opened successfully")
}

func main() {
    readFile("example.txt") // This will print: File opened successfully
}

In this example, defer ensures that the file is closed regardless of whether an error occurs during file processing.

Understanding Recover

A recover function can be used to regain control of a panicking goroutine. It stops the unwinding process and returns the value passed to panic. This allows you to handle errors gracefully without terminating the program.

Syntax

if r := recover(); r != nil {
    // Handle the panic here
}

Example

Let's combine defer, panic, and recover to create a more robust error handling mechanism:

package main

import "fmt"

func safeDivide(a, b int) (result int, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("panic occurred: %v", r)
        }
    }()

    result = a / b
    return
}

func main() {
    result, err := safeDivide(10, 2)
    if err != nil {
        fmt.Println(err) // This will not be printed
    } else {
        fmt.Println("Result:", result) // This will print: Result: 5
    }

    result, err = safeDivide(10, 0)
    if err != nil {
        fmt.Println(err) // This will print: panic occurred: runtime error: integer divide by zero
    } else {
        fmt.Println("Result:", result)
    }
}

In this example, the safeDivide function uses a deferred anonymous function to catch any panics that occur during division. If a panic is caught, it sets the err variable with an appropriate error message.

Best Practices

  1. Use Panic for Critical Errors: Only use panic for truly critical errors that cannot be recovered from within the current context. For recoverable errors, prefer returning errors using the error type.

  2. Limit Defer Usage: While defer is powerful, excessive use can lead to performance overhead and code complexity. Use it judiciously, especially in functions with multiple exit points.

  3. Avoid Deep Stacks with Panic: Deep call stacks can make debugging difficult. Try to keep the logic that might cause a panic as simple as possible.

  4. Use Recover for Cleanup: recover is best used for cleanup activities or logging errors before termination. Avoid complex error handling within recover blocks.

  5. Test Panics and Recovers: Write unit tests to ensure that your panic and recover mechanisms work as expected. This will help you catch potential issues early in the development process.

Conclusion

Understanding and effectively using panic, defer, and recover is crucial for building robust Go applications. By following best practices and combining these features appropriately, you can handle errors gracefully and maintain the stability of your software.

In this tutorial, we've covered the basics of panic, defer, and recover, along with real-world examples and best practices. With this knowledge, you'll be well-equipped to manage runtime errors in Go and write more reliable applications.


PreviousDefer StatementNext Arrays

Recommended Gear

Defer StatementArrays