Using Panic and Recover in Go

List Topics
February 18, 2025
No Comments
6 min read

In Go, panic and recover are mechanisms for handling unexpected situations or errors that might cause your program to crash. They allow you to handle critical errors that would otherwise stop the program. However, using them requires caution, as they can interrupt the normal flow of your program.

  • Panic is used when something goes wrong in the program, and it causes the program to stop executing.
  • Recover is used to regain control of a panicking goroutine, allowing the program to continue executing after handling the panic.

1️⃣ Panic in Go

When a function encounters a serious error, you can use panic to stop the execution of the current function and start unwinding the stack. It will propagate the panic up the call stack until it is either handled or causes the program to terminate.

🔹 Example:

Go
package main

import "fmt"

func divide(a, b int) int {
    if b == 0 {
        panic("division by zero")  // Panic if divisor is zero
    }
    return a / b
}

func main() {
    fmt.Println(divide(10, 2))  // Works fine
    fmt.Println(divide(10, 0))  // Causes panic
}

🔹 Output:

Bash
5
panic: division by zero

goroutine 1 [running]:
main.divide(0x8, 0x0, 0x0)
    /path/to/your/code/main.go:7 +0x64
main.main()
    /path/to/your/code/main.go:12 +0x54

👉 In this example, the panic is triggered when a division by zero is attempted, causing the program to terminate with a stack trace.

2️⃣ Recover in Go

The recover function can be used to stop a panic and regain control of the program. Recover only works if called inside a deferred function. It allows you to handle the panic and prevent the program from crashing.

🔹 Example:

Go
package main

import "fmt"

func divide(a, b int) int {
    if b == 0 {
        panic("division by zero")  // Panic if divisor is zero
    }
    return a / b
}

func safeDivide(a, b int) (result int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()
    result = divide(a, b)  // Call the function that may panic
    return
}

func main() {
    fmt.Println(safeDivide(10, 2))  // Works fine
    fmt.Println(safeDivide(10, 0))  // Recovers from panic
}

🔹 Output:

Bash
5
Recovered from panic: division by zero
0

👉 In this example, the safeDivide function wraps the call to divide. The panic that would occur when dividing by zero is caught by the recover() function inside the deferred function, and the program continues running.

3️⃣ When to Use Panic and Recover

  • Panic should be used in situations where the program cannot continue to run, like when an invalid state is encountered (e.g., invalid input, resource unavailability, etc.). It is not intended for handling recoverable errors, and should be reserved for situations where the program's behavior would be undefined without halting execution.
  • Recover should be used to handle situations where you can safely continue execution after a panic. It is often used to prevent crashes, allowing the program to gracefully handle an unexpected error without terminating.

4️⃣ Panic Example with Goroutines

Panic and recover can also be used with goroutines to handle errors in concurrent programming. If a goroutine panics, the program can recover from it to avoid stopping the entire execution.

🔹 Example:

Go
package main

import "fmt"

func worker(id int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("Goroutine %d recovered from panic: %v\n", id, r)
        }
    }()

    if id == 2 {
        panic("something went wrong in worker 2")  // Panic in goroutine 2
    }
    fmt.Printf("Worker %d finished successfully\n", id)
}

func main() {
    for i := 1; i <= 3; i++ {
        go worker(i)  // Launch workers in separate goroutines
    }

    // Sleep to allow goroutines to complete
    // In a real-world application, we would use sync mechanisms like WaitGroups instead of sleep
    fmt.Scanln() 
}

🔹 Output:

Bash
Worker 1 finished successfully
Goroutine 2 recovered from panic: something went wrong in worker 2
Worker 3 finished successfully

👉 In this example, goroutine 2 panics, but the recover function inside the defer block allows the program to recover from the panic, and the rest of the goroutines continue executing.

5️⃣ Important Notes on Panic and Recover

  • Panic is typically used in exceptional situations where recovery is not possible, and the program cannot continue running in a valid state.
  • Recover can only be used inside a deferred function. It allows the program to recover from a panic and continue executing, but it should not be used for regular error handling.
  • Defer is useful for cleanup tasks, like closing files or releasing resources, and it is executed even if a panic occurs.

Summary:

  • Panic is used to signal that something has gone critically wrong, and the program should stop executing.
  • Recover is used to catch a panic and allow the program to continue executing by handling the error.
  • Use panic when the program cannot continue in its current state, and use recover to handle errors gracefully and avoid crashes.
  • The combination of panic and recover is useful in scenarios involving concurrent programming (like goroutines), where errors in one part of the program should not crash the entire system.

Panic and recover are powerful tools for handling critical errors, but they should be used judiciously. Overusing panic can make your code harder to maintain and debug.


Panic এবং Recover ব্যবহার করা Go তে

Go তে panic এবং recover হল এমন কিছু মেকানিজম যা অবাঞ্ছিত পরিস্থিতি বা এরর হ্যান্ডলিংয়ের জন্য ব্যবহৃত হয়, যা আপনার প্রোগ্রামকে ক্র্যাশ হতে বাধা দিতে সাহায্য করে। এগুলো আপনাকে গম্ভীর ত্রুটি গুলি হ্যান্ডল করতে এবং প্রোগ্রামের চলমানতা বজায় রাখতে সাহায্য করে। তবে এগুলো ব্যবহারের ক্ষেত্রে সতর্কতা অবলম্বন করা উচিত, কারণ এগুলো প্রোগ্রামের সাধারণ প্রবাহকে ব্যাহত করতে পারে।

  • Panic ব্যবহৃত হয় যখন কিছু ভুল ঘটে এবং তা প্রোগ্রামের কার্যক্রম থামিয়ে দেয়।
  • Recover ব্যবহৃত হয় যখন একটি প্যানিক ঘটছে, তখন সেটি ধরে সেই গোরুটিনের কার্যক্রম আবার চালু করা যায়।

1️⃣ Panic in Go

যখন একটি ফাংশন কোনো গুরুতর ত্রুটি পায়, তখন panic ব্যবহার করা হয়, যার ফলে সেই ফাংশনের কার্যক্রম থেমে যায় এবং স্ট্যাক আনওন্ডিং শুরু হয়। প্যানিকটি কল স্ট্যাকের মাধ্যমে উপরের দিকে ছড়িয়ে পড়ে যতক্ষণ না সেটি হ্যান্ডেল না করা হয় অথবা প্রোগ্রাম বন্ধ হয়ে যায়।

🔹 উদাহরণ:

Go
package main

import "fmt"

func divide(a, b int) int {
    if b == 0 {
        panic("division by zero")  // যদি ভাগশেষ ০ হয় তবে panic করবে
    }
    return a / b
}

func main() {
    fmt.Println(divide(10, 2))  // এটি সঠিকভাবে কাজ করবে
    fmt.Println(divide(10, 0))  // এটি panic ঘটাবে
}

🔹 আউটপুট:

Bash
5
panic: division by zero

goroutine 1 [running]:
main.divide(0x8, 0x0, 0x0)
    /path/to/your/code/main.go:7 +0x64
main.main()
    /path/to/your/code/main.go:12 +0x54

👉 এই উদাহরণে, যখন ০ দিয়ে ভাগ করার চেষ্টা করা হয়, তখন panic ঘটিয়ে প্রোগ্রাম থেমে যায় এবং একটি স্ট্যাক ট্রেস প্রদর্শিত হয়।

2️⃣ Recover in Go

Recover ফাংশনটি একটি প্যানিককে ধরতে এবং প্রোগ্রামকে পুনরুদ্ধার করতে সাহায্য করে। Recover শুধুমাত্র তখন কাজ করবে যখন এটি একটি deferred ফাংশনের মধ্যে কল করা হয়। এটি প্যানিকের পর প্রোগ্রামকে চালু করতে সাহায্য করে, যাতে প্রোগ্রামটি ক্র্যাশ না হয়।

🔹 উদাহরণ:

Go
package main

import "fmt"

func divide(a, b int) int {
    if b == 0 {
        panic("division by zero")  // যদি ভাগশেষ ০ হয় তবে panic করবে
    }
    return a / b
}

func safeDivide(a, b int) (result int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()
    result = divide(a, b)  // প্যানিক ঘটানোর সম্ভাবনা রয়েছে
    return
}

func main() {
    fmt.Println(safeDivide(10, 2))  // এটি সঠিকভাবে কাজ করবে
    fmt.Println(safeDivide(10, 0))  // প্যানিক থেকে পুনরুদ্ধার করবে
}

🔹 আউটপুট:

Bash
5
Recovered from panic: division by zero
0

👉 এই উদাহরণে, safeDivide ফাংশনটি divide ফাংশনটিকে ঘিরে রাখে। ভাগশেষ ০ হলে প্যানিক ঘটে, তবে recover() ফাংশনটি সেই প্যানিককে ধরতে পারে এবং প্রোগ্রামটি ক্র্যাশ না হয়ে চলমান থাকে।

3️⃣ Panic ব্যবহার করার সময়

  • Panic তখন ব্যবহৃত হয় যখন প্রোগ্রামটি চলতে থাকলে অবৈধ বা অনির্দেশ্য আচরণ ঘটবে, এবং প্রোগ্রামটির জন্য গুরুত্বপূর্ণ পরিস্থিতি তৈরি হবে যা নিয়ে কাজ চালানো সম্ভব নয়।
  • Recover তখন ব্যবহার করা হয় যখন আপনি প্যানিক থেকে পুনরুদ্ধার করতে চান এবং প্রোগ্রামের কার্যক্রম পুনরায় চালু করতে চান।

4️⃣ Goroutines এর সাথে Panic এবং Recover

Panic এবং recover গোরুটিনের সাথে ব্যবহার করা যায়, যাতে গোরুটিনের মধ্যে ঘটে যাওয়া প্যানিক একমাত্র গোরুটিনটিকে থামিয়ে দেয়, পুরো প্রোগ্রামকে নয়।

🔹 উদাহরণ:

Go
package main

import "fmt"

func worker(id int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("Goroutine %d recovered from panic: %v\n", id, r)
        }
    }()

    if id == 2 {
        panic("something went wrong in worker 2")  // গোরুটিন ২ তে প্যানিক ঘটবে
    }
    fmt.Printf("Worker %d finished successfully\n", id)
}

func main() {
    for i := 1; i <= 3; i++ {
        go worker(i)  // আলাদা গোরুটিনে কাজের শুরু
    }

    // গোরুটিনের কাজ শেষ হতে কিছু সময় দেওয়া
    // বাস্তব ক্ষেত্রে, সিঙ্ক্রোনাইজেশনের জন্য WaitGroup এর মতো মেকানিজম ব্যবহার করতে হবে
    fmt.Scanln() 
}

🔹 আউটপুট:

Bash
Worker 1 finished successfully
Goroutine 2 recovered from panic: something went wrong in worker 2
Worker 3 finished successfully

👉 এখানে, গোরুটিন ২ প্যানিক করে, তবে recover() ফাংশনটি সেটিকে ধরতে পারে এবং প্রোগ্রামটি চালু থাকে।

5️⃣ Panic এবং Recover ব্যবহার করার সময় কিছু গুরুত্বপূর্ণ বিষয়

  • Panic এমন পরিস্থিতিতে ব্যবহার করা উচিত যখন প্রোগ্রামটি চলতে থাকা অবস্থা ঠিক রাখা সম্ভব নয়, যেমন অবৈধ ইনপুট, হারানো রিসোর্স ইত্যাদি।
  • Recover শুধুমাত্র deferred ফাংশনের মধ্যে ব্যবহৃত হতে পারে। এটি প্যানিক থেকে পুনরুদ্ধার করতে সাহায্য করে, কিন্তু এটি সাধারণ ত্রুটি হ্যান্ডলিংয়ের জন্য নয়।
  • Defer ফাংশন সাধারণত ক্লিনআপ কাজের জন্য ব্যবহৃত হয়, যেমন ফাইল বন্ধ করা বা রিসোর্স মুক্ত করা, এবং এটি প্যানিক ঘটলেও কার্যকর হয়।

সারসংক্ষেপ:

  • Panic ব্যবহৃত হয় প্রোগ্রামটি চলতে থাকার জন্য অবৈধ পরিস্থিতি তৈরি হলে, যেখানে প্রোগ্রামের অবস্থা সঠিক থাকে না।
  • Recover ব্যবহৃত হয় প্যানিক থেকে পুনরুদ্ধার করতে এবং প্রোগ্রামটি পুনরায় চালু রাখতে।
  • Panic এবং Recover একসাথে ব্যবহার করা হয় গোরুটিনের ক্ষেত্রে বা যেখানে ত্রুটির কারণে পুরো প্রোগ্রাম ক্র্যাশ না হয়।
  • এগুলি প্রোগ্রামের গম্ভীর ত্রুটির ক্ষেত্রে ব্যবহৃত হয়, তবে এগুলি অযথা ব্যবহার করা উচিত নয়।
©2025 Linux Bangla | Developed & Maintaind by Linux Bangla.