panic और recover
panic(value)
defer func() {
if r := recover(); r != nil {
// handle panic
}
}()
Triggering a panic
panic(value) call करना current function के normal execution को तुरंत रोक देता है और stack को unwind करना शुरू करता है, रास्ते में किसी भी deferred calls को चलाते हुए, जब तक कुछ recover न करे या program crash न हो।
उदाहरण: Triggering a panic
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define the function mustBePositive
func mustBePositive(n int) int {
// Check whether n < 0
if n < 0 {
panic("negative number not allowed")
}
// Send n back to the caller
return n
}
// main is where the program starts running
func main() {
// defer runs this call when the surrounding function returns
defer fmt.Println("this still runs during unwind")
// Print the values followed by a newline
fmt.Println(mustBePositive(5))
}
Login to try C/C++/Java/PHP code in the editor
Recovering from a panic
किसी deferred function के अंदर से call किया गया recover, panic को आगे propagate होने से रोकता है और panic को पास की गई value return करता है -- program को पूरी तरह crash होने के बजाय problem log करने और चलते रहने देते हुए।
उदाहरण: Recovering from a panic
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define the function safeDivide
func safeDivide(a, b int) (result int) {
// defer runs this call when the surrounding function returns
defer func() {
// Check whether r := recover(); r != nil
if r := recover(); r != nil {
// Print the values followed by a newline
fmt.Println("recovered from:", r)
result = 0
}
}()
// Send a / b back to the caller
return a / b
}
// main is where the program starts running
func main() {
fmt.Println(safeDivide(10, 0))
fmt.Println("program continues normally")
}
Login to try C/C++/Java/PHP code in the editor
panic vs Returning an Error
Idiomatic Go panic को programmer errors या genuinely unrecoverable स्थितियों (जैसे किसी required invariant का उल्लंघन) के लिए रखता है, जबकि साधारण, expected failure conditions -- एक गायब file, invalid input -- को इसके बजाय एक returned error के ज़रिए बताना चाहिए।
उदाहरण: panic vs Returning an Error
package main
import (
"errors"
"fmt"
)
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero") // expected failure: use error
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("handled gracefully:", err)
return
}
fmt.Println(result)
}
Login to try C/C++/Java/PHP code in the editor
- साधारण, expected error conditions के लिए एक error return करने के बजाय panic उपयोग करना -- panic genuinely exceptional स्थितियों के लिए रखा गया है।
- किसी deferred function के बाहर recover() call करना, जहां इसका कोई असर नहीं होता और यह हमेशा nil return करता है।
- यह भूल जाना कि recover सिर्फ उस goroutine में panic को रोकता है जहां इसे call किया जाता है -- यह किसी दूसरे goroutine में हो रहे panic को recover नहीं कर सकता।
- panic तुरंत normal execution रोक देता है और call stack को unwind करना शुरू करता है, रास्ते में deferred calls चलाते हुए।
- किसी deferred function के अंदर call किया गया recover, चल रहे panic को रोकता है और program को जारी रहने देता है।
- panic/recover genuinely exceptional स्थितियों के लिए रखा गया है -- normal error returns का विकल्प नहीं।
- एक unrecovered panic पूरे program को एक stack trace के साथ crash कर देता है।
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: