Go में त्रुटि प्रबंधन: दर्शन और व्यवहार
\n\nकई आधुनिक भाषाओं के विपरीत, Go (Golang) क्लासिक try/catch संरचना का उपयोग नहीं करता है। इसके बजाय, Go डेवलपर्स "त्रुटियाँ मान के रूप में" (errors as values) दृष्टिकोण का पालन करते हैं। यह कोड को अधिक स्पष्ट, पूर्वानुमानित और सुरक्षित बनाता है। इस लेख में, हम Go में त्रुटि प्रबंधन के सभी पहलुओं को कवर करेंगे: बुनियादी पैटर्न से लेकर defer, panic और recover के साथ उन्नत तकनीकों तक।
1. मूल बातें: त्रुटियाँ सिर्फ मान हैं
\n\nGo में, त्रुटि एक इंटरफ़ेस error है जिसमें एकमात्र विधि Error() string है। कोई भी फ़ंक्शन जो विफल हो सकता है, अंतिम वापसी मान के रूप में एक त्रुटि लौटाता है।
package main\n\nimport (\n "errors"\n "fmt"\n)\n\n// त्रुटि वापस करने वाला विभाजन फ़ंक्शन\nfunc divide(a, b float64) (float64, error) {\n if b == 0 {\n return 0, errors.New("शून्य से विभाजन संभव नहीं")\n }\n return a / b, nil\n}\n\nfunc main() {\n result, err := divide(10, 0)\n if err != nil {\n fmt.Println("त्रुटि:", err)\n return\n }\n fmt.Println("परिणाम:", result)\n}\n\nमुख्य बिंदु: if err != nil जाँच Go में त्रुटियों को संभालने का मानक तरीका है। कोई छिपा हुआ अपवाद नहीं है जो अप्रत्याशित रूप से "उछल" सकता है।
2. त्रुटियाँ बनाना और अनुकूलित करना
\n\nGo त्रुटियाँ बनाने के कई तरीके प्रदान करता है:
\n\n- \n
errors.New()— सरल पाठ्य त्रुटि। \n fmt.Errorf()— फ़ॉर्मेटिंग के साथ त्रुटि (%wको रैपिंग के लिए सपोर्ट करता है)। \n - कस्टम प्रकार — अतिरिक्त संदर्भ प्रसारित करने के लिए। \n
अतिरिक्त डेटा के साथ कस्टम त्रुटि
\n\ntype DivisionError struct {\n Dividend float64\n Divisor float64\n Message string\n}\n\nfunc (e *DivisionError) Error() string {\n return fmt.Sprintf("%s: %f / %f", e.Message, e.Dividend, e.Divisor)\n}\n\nfunc safeDivide(a, b float64) (float64, error) {\n if b == 0 {\n return 0, &DivisionError{\n Dividend: a,\n Divisor: b,\n Message: "शून्य से विभाजन",\n }\n }\n return a / b, nil\n}\n\nfunc main() {\n _, err := safeDivide(10, 0)\n if err != nil {\n // अतिरिक्त फ़ील्ड प्राप्त करने के लिए Type assertion\n var divErr *DivisionError\n if errors.As(err, &divErr) {\n fmt.Printf("%f को %f से विभाजित करने में त्रुटि: %s\\n", divErr.Dividend, divErr.Divisor, divErr.Message)\n }\n }\n}\n\nerrors.As() का उपयोग यह जाँचने की अनुमति देता है कि त्रुटि एक विशिष्ट प्रकार की है या नहीं और उससे डेटा निकाल सकता है। यह अन्य भाषाओं में instanceof के समान है।
3. त्रुटि प्रबंधन पैटर्न: सरल से जटिल तक
\n\nGo में त्रुटियों के साथ काम करने के कई स्थापित पैटर्न हैं:
\n\n3.1. Sentinel errors (मार्कर त्रुटियाँ)
\nये पूर्वनिर्धारित त्रुटियाँ हैं जिनकी तुलना == से की जा सकती है। उदाहरण: io.EOF।
import (\n "errors"\n "fmt"\n)\n\nvar ErrNotFound = errors.New("आइटम नहीं मिला")\n\nfunc findUser(id int) (string, error) {\n if id != 1 {\n return "", ErrNotFound\n }\n return "Alice", nil\n}\n\nfunc main() {\n _, err := findUser(2)\n if errors.Is(err, ErrNotFound) {\n fmt.Println("उपयोगकर्ता नहीं मिला, नया बना रहे हैं...")\n }\n}\n\n3.2. Wrapping errors (त्रुटियों को लपेटना)
\nGo 1.13 से शुरू करके, fmt.Errorf में %w के साथ त्रुटियों को लपेटा जा सकता है। यह त्रुटि श्रृंखला को संरक्षित करता है।
func readConfig(path string) error {\n data, err := os.ReadFile(path)\n if err != nil {\n return fmt.Errorf("कॉन्फ़िग %s पढ़ना: %w", path, err)\n }\n // ... डेटा प्रोसेसिंग\n