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.
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:
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:
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.
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:
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:
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.
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:
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:
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.
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.
Go তে panic এবং recover হল এমন কিছু মেকানিজম যা অবাঞ্ছিত পরিস্থিতি বা এরর হ্যান্ডলিংয়ের জন্য ব্যবহৃত হয়, যা আপনার প্রোগ্রামকে ক্র্যাশ হতে বাধা দিতে সাহায্য করে। এগুলো আপনাকে গম্ভীর ত্রুটি গুলি হ্যান্ডল করতে এবং প্রোগ্রামের চলমানতা বজায় রাখতে সাহায্য করে। তবে এগুলো ব্যবহারের ক্ষেত্রে সতর্কতা অবলম্বন করা উচিত, কারণ এগুলো প্রোগ্রামের সাধারণ প্রবাহকে ব্যাহত করতে পারে।
যখন একটি ফাংশন কোনো গুরুতর ত্রুটি পায়, তখন panic ব্যবহার করা হয়, যার ফলে সেই ফাংশনের কার্যক্রম থেমে যায় এবং স্ট্যাক আনওন্ডিং শুরু হয়। প্যানিকটি কল স্ট্যাকের মাধ্যমে উপরের দিকে ছড়িয়ে পড়ে যতক্ষণ না সেটি হ্যান্ডেল না করা হয় অথবা প্রোগ্রাম বন্ধ হয়ে যায়।
🔹 উদাহরণ:
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 ঘটাবে
}
🔹 আউটপুট:
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
ঘটিয়ে প্রোগ্রাম থেমে যায় এবং একটি স্ট্যাক ট্রেস প্রদর্শিত হয়।
Recover ফাংশনটি একটি প্যানিককে ধরতে এবং প্রোগ্রামকে পুনরুদ্ধার করতে সাহায্য করে। Recover শুধুমাত্র তখন কাজ করবে যখন এটি একটি deferred ফাংশনের মধ্যে কল করা হয়। এটি প্যানিকের পর প্রোগ্রামকে চালু করতে সাহায্য করে, যাতে প্রোগ্রামটি ক্র্যাশ না হয়।
🔹 উদাহরণ:
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)) // প্যানিক থেকে পুনরুদ্ধার করবে
}
🔹 আউটপুট:
5
Recovered from panic: division by zero
0
👉 এই উদাহরণে, safeDivide
ফাংশনটি divide
ফাংশনটিকে ঘিরে রাখে। ভাগশেষ ০ হলে প্যানিক ঘটে, তবে recover()
ফাংশনটি সেই প্যানিককে ধরতে পারে এবং প্রোগ্রামটি ক্র্যাশ না হয়ে চলমান থাকে।
Panic এবং recover গোরুটিনের সাথে ব্যবহার করা যায়, যাতে গোরুটিনের মধ্যে ঘটে যাওয়া প্যানিক একমাত্র গোরুটিনটিকে থামিয়ে দেয়, পুরো প্রোগ্রামকে নয়।
🔹 উদাহরণ:
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()
}
🔹 আউটপুট:
Worker 1 finished successfully
Goroutine 2 recovered from panic: something went wrong in worker 2
Worker 3 finished successfully
👉 এখানে, গোরুটিন ২ প্যানিক করে, তবে recover()
ফাংশনটি সেটিকে ধরতে পারে এবং প্রোগ্রামটি চালু থাকে।