Go में एरर हैंडलिंग: try/catch और उन्नत तकनीकें

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Go में एरर हैंडलिंग: try/catch और उन्नत तकनीकें

\n\n

Java, Python, JavaScript जैसी आधुनिक भाषाओं के विपरीत, Go में पारंपरिक try/catch/finally कंस्ट्रक्ट नहीं है। दूसरे इकोसिस्टम से आने वाले डेवलपर्स इसे अक्सर एक कमी मानते हैं। लेकिन Go का दर्शन एरर को संभालने का एक स्पष्ट और अनुमानित तरीका प्रदान करता है। इस लेख में हम Go में एरर हैंडलिंग की उन्नत तकनीकों को समझेंगे: बुनियादी सिद्धांतों से लेकर panic/recover, एरर रैपिंग और कस्टम टाइप्स के साथ लचीली सिस्टम बनाने तक।

\n\n

1. Go में try/catch क्यों नहीं है?

\n\n

मुख्य कारण है कोड की सादगी और पठनीयता। Go में एरर सिर्फ एक वैल्यू (error) है जिसे फंक्शन अंतिम रिजल्ट के रूप में रिटर्न करता है। डेवलपर इस वैल्यू को स्पष्ट रूप से चेक करता है, न कि छिपे हुए एक्सेप्शन फ्लो पर निर्भर करता है। इससे प्रोग्राम का निष्पादन प्रवाह स्पष्ट रहता है।

\n\n

स्टैंडर्ड पैटर्न इस प्रकार है:

\n\n
package main\n\nimport (\n    "fmt"\n    "os"\n)\n\nfunc readFile(name string) ([]byte, error) {\n    data, err := os.ReadFile(name)\n    if err != nil {\n        return nil, fmt.Errorf("फ़ाइल %s पढ़ने में विफल: %w", name, err)\n    }\n    return data, nil\n}\n\nfunc main() {\n    data, err := readFile("config.json")\n    if err != nil {\n        fmt.Println("एरर:", err)\n        return\n    }\n    fmt.Println("डेटा:", string(data))\n}
\n\n

यहाँ हर संभावित एरर को स्पष्ट रूप से हैंडल किया गया है। यह "शोर" नहीं है, बल्कि यह गारंटी है कि प्रोग्रामर ने संभावित विफलता के बारे में सोचा है।

\n\n

2. उन्नत तकनीकें: एरर रैपिंग और चेन

\n\n

Go 1.13 ने fmt.Errorf में %w के माध्यम से एरर रैपिंग का समर्थन पेश किया। यह एरर की चेन बनाने की अनुमति देता है, जबकि मूल कारण को संरक्षित रखता है। ऐसी चेन को अनपैक करने के लिए errors.Is और errors.As फंक्शन का उपयोग किया जाता है।

\n\n

रैपिंग और जाँच का उदाहरण:

\n\n
package main\n\nimport (\n    "errors"\n    "fmt"\n)\n\nvar ErrNotFound = errors.New("रिकॉर्ड नहीं मिला")\n\nfunc findUser(id int) (string, error) {\n    if id != 42 {\n        return "", fmt.Errorf("उपयोगकर्ता %d खोजें: %w", id, ErrNotFound)\n    }\n    return "Alice", nil\n}\n\nfunc main() {\n    _, err := findUser(100)\n    if errors.Is(err, ErrNotFound) {\n        fmt.Println("एरर: रिकॉर्ड मौजूद नहीं है। विवरण:", err)\n    } else {\n        fmt.Println("अज्ञात एरर:", err)\n    }\n}
\n\n

टाइप किए गए एरर के लिए errors.As का उपयोग:

\n\n
package main\n\nimport (\n    "errors"\n    "fmt"\n)\n\ntype ValidationError struct {\n    Field string\n    Msg   string\n}\n\nfunc (e *ValidationError) Error() string {\n    return fmt.Sprintf("फ़ील्ड %s की वैलिडेशन एरर: %s", e.Field, e.Msg)\n}\n\nfunc validateAge(age int) error {\n    if age < 0 {\n        return &ValidationError{Field: "age", Msg: "उम्र नकारात्मक नहीं हो सकती"}\n    }\n    return nil\n}\n\nfunc main() {\n    err := validateAge(-5)\n    var ve *ValidationError\n    if errors.As(err, &ve) {\n        fmt.Printf("फ़ील्ड: %s, संदेश: %s\\n", ve.Field, ve.Msg)\n    } else {\n        fmt.Println("अज्ञात एरर:", err)\n    }\n}
\n\n

3. Panic और Recover: आपातकालीन पुनर्प्राप्ति

\n\n

Go में panic एक्सेप्शन के समान है, लेकिन इसका उपयोग केवल वास्तविक असाधारण स्थितियों (जैसे प्रोग्रामर की तार्किक त्रुटि, शून्य से भाग, ऐरे की सीमा से बाहर जाना) के लिए किया जाना चाहिए। recover पैनिक को पकड़ने और निष्पादन को बहाल करने की अनुमति देता है।

\n\n

महत्वपूर्ण: recover केवल डिफर्ड फंक्शन (defer) के अंदर काम करता है। सामान्य उपयोग HTTP सर्वर में मिडलवेयर या गोरूटीन की सुरक्षा है।

\n\n

सुरक्षित गोरूटीन लॉन्च का उदाहरण:

\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n)\n\nfunc safeGoroutine(fn func()) {\n    go func() {\n        defer func() {\n            if r := recover(); r != nil {\n                fmt.Println("गोरूटीन में पैनिक पकड़ा गया:", r)\n            }\n        }()\n        fn()\n    }()\n}\n\nfunc main() {\n    safeGoroutine(func() {\n        panic("कुछ गलत हो गया!")\n    })\n    time.Sleep(time.Second)\n    fmt.Println("प्रोग्राम जारी है...")  \n}
\n\n

यह पैटर्न विशेष रूप से लंबे समय तक चलने वाली सेवाओं में उपयोगी है, जहाँ एक गोरूटीन की विफलता से पूरा एप्लिकेशन क्रैश नहीं होना चाहिए।

\n\n

4. कस्टम एरर टाइप्स और अतिरिक्त संदर्भ

\n\n

जटिल एप्लिकेशन में, केवल एरर स्ट्रिंग पर्याप्त नहीं है। आप स्ट्रक्ट बना सकते हैं जो error इंटरफ़ेस को लागू करते हैं और अतिरिक्त जानकारी (HTTP स्थिति कोड, टाइमस्टैम्प, आंतरिक कोड) संग्रहीत करते हैं।

\n\n

उदाहरण: HTTP एरर रैपर

\n\n
package main\n\nimport (\n    "fmt"\n    "net/http"\n)\n\ntype HTTPError struct {\n    Code    int\n    Message string\n    Err     error\n}\n\nfunc (e *HTTPError) Error() string {\n    return fmt.Sprintf("HTTP %d: %s (कारण: %v)", e.Code, e.Message, e.Err)\n}\n\nfunc (e *HTTPError) Unwrap() error {\n    return e.Err\n}\n\nfunc fetchData(url string) (string, error) {\n    resp, err := http.Get(url)\n    if err != nil {\n        return "", &HTTPError{Code: 500, Message: "सर्वर से कनेक्ट नहीं हो सका", Err: err}\n    }\n    defer resp.Body.Close()\n    if resp.StatusCode != 200 {\n        return "", &HTTPError{Code: resp.StatusCode, Message: "गलत प्रतिक्रिया", Err: nil}\n    }\n    return "डेटा प्राप्त हुआ", nil\n}\n\nfunc main() {\n    _, err := fetchData("https://example.com/api")\n    var httpErr *HTTPError\n    if errors.As(err, &httpErr) {\n        fmt.Printf("HTTP एरर: कोड=%d, संदेश=%s\\n", httpErr.Code, httpErr.Message)\n    }\n}
\n\n

निष्कर्ष

\n\n

Go में एरर हैंडलिंग पहली बार में असामान्य लग सकती है, लेकिन यह कोड को अधिक पूर्वानुमानित और बनाए रखने में आसान बनाती है। errors.Is, errors.As, एरर रैपिंग और कस्टम टाइप्स जैसी उन्नत तकनीकों का उपयोग करके, आप मजबूत सिस्टम बना सकते हैं जो विफलताओं को सुरुचिपूर्ण ढंग से संभालते हैं। याद रखें: panic का उपयोग केवल वास्तविक आपात स्थितियों के लिए करें, और recover का उपयोग केवल तब करें जब आप जानते हों कि आप क्या कर रहे हैं।

ब्लॉग

पुस्तक अनुशंसाएँ