KoderKoder.ai
प्राइसिंगएंटरप्राइज़शिक्षानिवेशकों के लिए
लॉग इनशुरू करें

उत्पाद

प्राइसिंगएंटरप्राइज़निवेशकों के लिए

संसाधन

हमसे संपर्क करेंसपोर्टशिक्षाब्लॉग

कानूनी

प्राइवेसी पॉलिसीउपयोग की शर्तेंसुरक्षास्वीकार्य उपयोग नीतिदुरुपयोग रिपोर्ट करें

सोशल

LinkedInTwitter
Koder.ai
भाषा

© 2026 Koder.ai. सर्वाधिकार सुरक्षित।

होम›ब्लॉग›स्पष्ट और सुसंगत प्रतिक्रियाओं के लिए Go API त्रुटि हैंडलिंग पैटर्न
29 सित॰ 2025·8 मिनट

स्पष्ट और सुसंगत प्रतिक्रियाओं के लिए Go API त्रुटि हैंडलिंग पैटर्न

Go API त्रुटि हैंडलिंग पैटर्न जो टाइप्ड एरर, HTTP स्टेटस मैपिंग, request IDs और सुरक्षित संदेशों को मानकीकृत करके इंटरनल्स लीक होने से रोकते हैं।

स्पष्ट और सुसंगत प्रतिक्रियाओं के लिए Go API त्रुटि हैंडलिंग पैटर्न

असंगत API त्रुटियाँ क्लाइंट्स को क्यों परेशान करती हैं

जब हर एंडपॉइंट विफलताओं की रिपोर्ट अलग तरीके से करता है, तो क्लाइंट्स आपकी API पर भरोसा करना बंद कर देते हैं। एक रूट लौटाता है { "error": "not found" }, दूसरा { "message": "missing" } लौटाता है, और तीसरा साधारण टेक्स्ट भेज देता है। अर्थ करीब भी हो सकता है, लेकिन क्लाइंट को अब अंदाज़ा लगाना पड़ता है कि क्या हुआ।

लागत जल्दी दिखती है। टीमें नाज़ुक पार्सिंग लॉजिक बनाती हैं और हर एंडपॉइंट के लिए स्पेशल केस जोड़ती हैं। रिट्राइज रिस्की हो जाते हैं क्योंकि क्लाइंट यह नहीं बता सकता कि "फिर से कोशिश करें" या "आपका इनपुट गलत है"। सपोर्ट टिकट बढ़ते हैं क्योंकि क्लाइंट केवल एक अस्पष्ट संदेश देखता है, और आपकी टीम आसानी से इसे सर्वर-लॉग लाइन से मैच नहीं कर पाती।

एक साधारण परिदृश्य: एक मोबाइल ऐप साइनअप के दौरान तीन एंडपॉइंट्स को कॉल करता है। पहला HTTP 400 लौटाता है फ़ील्ड-स्तर त्रुटि मैप के साथ, दूसरा HTTP 500 के साथ एक स्टैक ट्रेस स्टリング लौटाता है, और तीसरा HTTP 200 के साथ { "ok": false } लौटाता है। ऐप टीम तीन अलग त्रुटि हैंडलर शिप करती है, और बैकएंड टीम को अभी भी रिपोर्ट मिलती है जैसे "signup कभी-कभी फेल होता है" बिना किसी सुराग के।

लक्ष्य एक पूर्वानुमेय कॉन्ट्रैक्ट है। क्लाइंट्स को भरोसेमंद तरीके से पढ़ना चाहिए कि क्या हुआ—क्या उनकी गलती थी या आपकी, क्या retry समझदारी है, और एक request ID जिसे वे सपोर्ट में पेस्ट कर सकें।

स्कोप नोट: यह JSON HTTP APIs (gRPC नहीं) पर केंद्रित है, लेकिन वही विचार किसी भी जगह लागू होते हैं जहाँ आप अन्य सिस्टम्स को त्रुटियाँ लौटाते हैं।

एक सरल लक्ष्य: हर एंडपॉइंट एक ही कॉन्ट्रैक्ट फॉलो करे

एक स्पष्ट कॉन्ट्रैक्ट चुनें और हर एंडपॉइंट को उसका पालन कराएँ। “सुसंगत” का मतलब है वही JSON आकार, फ़ील्ड्स का वही अर्थ, और वही व्यवहार चाहे कौन-सा हैंडलर फेल हुआ हो। एक बार ऐसा होने पर, क्लाइंट्स अनुमान लगाना बंद कर देंगे और त्रुटियों को हैंडल करने लगेंगे।

एक उपयोगी कॉन्ट्रैक्ट क्लाइंट्स को बताता है कि आगे क्या करना है। अधिकांश ऐप्स के लिए, हर त्रुटि उत्तर को तीन प्रश्नों का उत्तर देना चाहिए:

  • क्या मैं अपना इनपुट ठीक कर सकता हूँ?
  • क्या मुझे बाद में retry करना चाहिए?
  • क्या मुझे सपोर्ट से संपर्क करने की आवश्यकता है?

व्यावहारिक नियमों का सेट:

  • सभी त्रुटियों के लिए एक response schema।
  • एक status-code नीति (एक ही एरर प्रकार हमेशा एक ही HTTP स्टेटस पर मैप होता है)।
  • एक safe message नीति (क्या यूज़र्स देख सकते हैं बनाम क्या इंटरनल रहता है)।
  • एक correlation हुक (एक request ID जो सपोर्ट को फेलियर खोजने में मदद करे)।

पहले से तय कर लें कि क्या वस्तुएँ कभी response में नहीं दिखनी चाहिए। सामान्य “कभी नहीं” आइटम में SQL फ्रैगमेंट, स्टैक ट्रेस, आंतरिक होस्टनेम, सीक्रेट्स, और डिपेंडेंसी से मिलने वाले कच्चे एरर स्ट्रिंग्स शामिल हैं।

एक साफ़ विभाजन रखें: एक छोटा यूज़र-फेसिंग संदेश (सुरक्षित, विनम्र, कार्रवाईयोग्य) और आंतरिक विवरण (पूर्ण त्रुटि, स्टैक, और संदर्भ) लॉग्स में रखें। उदाहरण के लिए, “Could not save your changes. Please try again.” सुरक्षित है। “pq: duplicate key value violates unique constraint users_email_key” सुरक्षित नहीं है।

जब हर एंडपॉइंट एक ही कॉन्ट्रैक्ट फॉलो करे, तो क्लाइंट एक ही त्रुटि हैंडलर बना सकता है और उसे हर जगह पुन: उपयोग कर सकता है।

एक ऐसा त्रुटि उत्तर स्कीमा परिभाषित करें जिस पर क्लाइंट भरोसा कर सकें

क्लाइंट्स तभी त्रुटियों को साफ़-सुथरे ढंग से हैंडल कर सकते हैं जब हर एंडपॉइंट एक ही आकार में जवाब दे। एक JSON एंवेलप चुनें और उसे स्थिर रखें।

एक व्यावहारिक डिफ़ॉल्ट है एक error ऑब्जेक्ट प्लस शीर्ष-स्तर request_id:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Some fields are invalid.",
    "details": {
      "fields": {
        "email": "must be a valid email address"
      }
    }
  },
  "request_id": "req_01HV..."
}

HTTP स्टेटस व्यापक श्रेणी देता है (400, 401, 409, 500)। मशीन-रीडेबल error.code क्लाइंट के लिए विशिष्ट केस देता है जिस पर वह ब्रांच कर सके। यह विभाजन इसलिए महत्वपूर्ण है क्योंकि कई अलग समस्याएँ एक ही स्टेटस शेयर कर सकती हैं। एक मोबाइल ऐप EMAIL_TAKEN और WEAK_PASSWORD के लिए अलग UI दिखाना चाहेगा, भले ही दोनों 400 हों।

error.message को सुरक्षित और मानव-सुमुखी रखें। यह उपयोगकर्ता को समस्या सुधारने में मदद करना चाहिए, पर इंटरनल्स कभी लीक न करें (SQL, स्टैक ट्रेसेस, प्रोवाइडर नाम, फ़ाइल पथ)।

वैकल्पिक फ़ील्ड्स उपयोगी होते हैं जब वे पूर्वानुमेय बने रहें:

  • वैलिडेशन त्रुटियाँ: details.fields एक मैप के रूप में फ़ील्ड से संदेश।
  • रेट लिमिट या अस्थायी समस्याएँ: details.retry_after_seconds।
  • अतिरिक्त मार्गदर्शन: details.docs_hint सादा टेक्स्ट के रूप में (URL नहीं)।

बैकवर्ड कम्पैटिबिलिटी के लिए, error.code मानों को अपनी API कॉन्ट्रैक्ट का हिस्सा समझें। नए कोड जोड़ें बिना पुराने अर्थ बदले। केवल वैकल्पिक फ़ील्ड जोड़ें, और मान लें कि क्लाइंट अज्ञात फ़ील्ड्स को इग्नोर कर देगा।

Go में टाइप्ड एरर: आपके हैंडलर्स के लिए एक साफ मॉडल

जब हर हैंडलर अपनी विफलता संकेत करने का अपना तरीका बनाता है तो एरर हैंडलिंग जटिल हो जाती है। कुछ टाइप्ड एरर से यह सुधार जाता है: हैंडलर्स ज्ञात एरर टाइप लौटाएँ, और एक रेस्पॉन्स लेयर उन्हें सुसंगत उत्तरों में बदल दे।

एक व्यावहारिक स्टार्टर सेट अधिकांश एंडपॉइंट्स को कवर कर देता है:

  • ValidationError (गलत इनपुट)
  • NotFoundError (संसाधन मौजूद नहीं)
  • ConflictError (यूनिक कन्स्ट्रेंट, स्टेट मिसमैच)
  • UnauthorizedError (लॉग इन नहीं या अनुमति नहीं)
  • InternalError (बाकी सब)

कुंजी यह है कि शीर्ष स्तर पर स्थिरता रहे, भले ही मूल कारण बदले। आप लोअर-लेवल एरर्स (SQL, नेटवर्क, JSON पार्सिंग) को रैप कर सकते हैं पर वही सार्वजनिक प्रकार लौटाएँ जिसे मिडलवेयर पहचान सके।

type NotFoundError struct {
	Resource string
	ID       string
	Err      error // private cause
}

func (e NotFoundError) Error() string { return "not found" }
func (e NotFoundError) Unwrap() error { return e.Err }

अपने हैंडलर में, सीधे sql.ErrNoRows लीक करने की बजाय NotFoundError{Resource: "user", ID: id, Err: err} लौटाएँ।

एरर्स चेक करने के लिए, कस्टम टाइप्स के लिए errors.As और सेंटिनल एरर्स के लिए errors.Is पसंद करें। सेंटिनल एरर्स (जैसे var ErrUnauthorized = errors.New("unauthorized")) साधारण मामलों के लिए काम करते हैं, पर जब आपको सुरक्षित संदर्भ (जैसे कौन-सा रिसोर्स गायब था) चाहिए तो कस्टम टाइप्स बेहतर हैं बिना आपकी सार्वजनिक प्रतिक्रिया कॉन्ट्रैक्ट बदले।

जो चीज़ें आप जोड़ते हैं उन पर सख्ती बरतें:

  • सार्वजनिक (क्लाइंट्स के लिए सुरक्षित): एक छोटा संदेश, एक स्थिर कोड, और कभी-कभी वैलिडेशन के लिए फ़ील्ड नाम।
  • निजी (केवल लॉग्स): मूल Err, स्टैक जानकारी, कच्चे SQL एरर्स, टोकन, उपयोगकर्ता डेटा।

यह विभाजन आपको क्लाइंट्स की मदद करने देता है बिना इंटरनल्स उजागर किए।

एरर प्रकारों को HTTP स्टेटस कोड्स पर सुसंगत रूप से मैप करें

एक बार जब आपके पास टाइप्ड एरर हों, अगला काम उबाऊ पर आवश्यक है: वही एरर प्रकार हमेशा वही HTTP स्टेटस पैदा करे। क्लाइंट्स उसी के आधार पर लॉजिक बनाएंगे।

एक व्यावहारिक मैपिंग जो अधिकांश APIs पर काम करती है:

Error type (example)StatusWhen to use it
BadRequest (malformed JSON, missing required query param)400The request is not valid at a basic protocol or format level.
Unauthenticated (no/invalid token)401The client needs to authenticate.
Forbidden (no permission)403Auth is valid, but access is not allowed.
NotFound (resource ID does not exist)404The requested resource is not there (or you choose to hide existence).
Conflict (unique constraint, version mismatch)409The request is well-formed, but it clashes with current state.
ValidationFailed (field rules)422The shape is fine, but business validation fails (email format, min length).
RateLimited429Too many requests in a time window.
Internal (unknown error)500Bug or unexpected failure.
Unavailable (dependency down, timeout, maintenance)503Temporary server-side issue.

दो विभेद जो बहुत भ्रम रोकते हैं:

  • 400 बनाम 422: 400 तब उपयोग करें जब आप रिक्वेस्ट को भरोसेमंद तरीके से इंटरप्रेट नहीं कर सकते (बिगड़ा JSON, गलत प्रकार)। 422 तब उपयोग करें जब आप इसे पार्स कर सकते हैं पर मान स्वीकार्य नहीं हैं।
  • 409 बनाम 422: 422 फील्ड-स्तर वैलिडेशन के लिए; 409 तब जब डेटा वैध हो पर लागू नहीं हो सकता क्योंकि स्टेट टकरा रहा है (ईमेल पहले से मौजूद, ऑर्डर पहले ही शिप हो चुका)।

Retry मार्गदर्शन मायने रखता है:

  • आमतौर पर retry सुरक्षित: 503, और कभी-कभी 429 (इंतज़ार के बाद)।
  • आमतौर पर बिना बदलाव के retry सुरक्षित नहीं: 400, 401, 403, 404, 409, 422।
  • यदि ऑपरेशन idempotent है (एक ही बॉडी के साथ PUT, या POST के साथ idempotency key), तो ट्रांज़िएंट फेलियर्स के बाद retries भी सुरक्षित हो सकते हैं।

Request IDs: क्लाइंट मुद्दों को डिबग करने का सबसे तेज़ तरीका

समय के साथ कोड स्थिर रखें
एक बार त्रुटि कोड कैटलॉग लिखें, फिर नए एंडपॉइंट्स में उसे पुन: उपयोग करें।
योजना शुरू करें

एक request ID एक छोटा यूनिक वैल्यू है जो एक API कॉल को end-to-end पहचानता है। अगर क्लाइंट हर उत्तर में इसे देख सके, तो सपोर्ट आसान हो जाता है: “मुझे request ID भेजें” अक्सर सही लॉग और फेलियर खोजने के लिए काफी होता है।

यह आदत सफलता और त्रुटि दोनों उत्तरों के लिए उपयोगी है।

जनरेशन और प्रॉपेगेशन नियम

एक स्पष्ट नियम अपनाएँ: अगर क्लाइंट request ID भेजता है, तो उसे रखें। अगर नहीं भेजता, तो नया बनाइए।

  • एक ही हेडर नाम से इनकमिंग ID स्वीकार करें (एक चुनें और डॉक्यूमेंट करें, उदाहरण के लिए X-Request-Id).
  • अगर हेडर मिसिंग या खाली हो, तो एज (middleware) पर नया ID जेनरेट करें और उसे request context में अटैच करें।
  • ID को रीक्वेस्ट के दौरान कभी बदलें नहीं। इसे डाउनस्ट्रीम कॉल्स (DB, अन्य सर्विसेस) तक context या हेडर्स के माध्यम से पास करें।

request ID को तीन जगह रखें:

  • Response header (उसी हेडर नाम में जिसे आप स्वीकार करते हैं)
  • Response body (आपके मानक स्कीमा में request_id के रूप में)
  • Logs (हर लॉग लाइन पर structured फ़ील्ड के रूप में)

बैच और असिंक्रोनस वर्क

बैच एंडपॉइंट्स या बैकग्राउंड जॉब्स के लिए एक parent request ID रखें। उदाहरण: क्लाइंट 200 पंक्तियाँ अपलोड करता है, 12 वैलिडेशन में फेल होती हैं, और आप वर्क enqueue करते हैं। पूरे कॉल के लिए एक request_id लौटाएँ, और प्रत्येक जॉब व प्रत्येक प्रति-आइटम त्रुटि पर parent_request_id शामिल करें। इस तरह आप "एक अपलोड" को ट्रेस कर सकते हैं भले ही वह बहुत से टास्क में फैल जाए।

इंटरनल्स लीक किए बिना लॉगिंग और मेट्रिक्स

क्लाइंट्स को एक साफ, स्थिर त्रुटि उत्तर चाहिए। आपके लॉग्स को गंदी सच्चाई चाहिए। उन दोनों दुनियाओं को अलग रखें: क्लाइंट को सुरक्षित संदेश और सार्वजनिक एरर कोड दें, जबकि इंटरनल कारण, स्टैक और संदर्भ सर्वर पर लॉग करें।

हर त्रुटि उत्तर के लिए एक संरचित ईवेंट लॉग करें, जिसे request_id से खोजा जा सके।

रखने योग्य फ़ील्ड्स:

  • request_id
  • user_id या account_id (जब authenticated हो)
  • public error code और HTTP status
  • handler/route नाम और method
  • internal error detail (wrapped cause, validation field errors, upstream timeout)

आंतरिक विवरण केवल सर्वर लॉग्स (या आंतरिक त्रुटि स्टोर) में रखें। क्लाइंट कभी भी कच्चे डेटाबेस एरर्स, क्वेरी टेक्स्ट, स्टैक ट्रेसेस, या प्रोवाइडर संदेश नहीं देखना चाहिए। यदि आप कई सर्विसेस चलाते हैं, तो एक आंतरिक फ़ील्ड जैसे source (api, db, auth, upstream) त्रैज में तेज़ी ला सकता है।

शोर वाले एंडपॉइंट्स और rate-limited एरर्स पर नज़र रखें। अगर एक एंडपॉइंट हजारों बार प्रति मिनट समान 429 या 400 पैदा कर सकता है, तो लॉग स्पैम से बचें: रिपीटेड ईवेंट्स को सैंपल करें, या अपेक्षित एरर्स केSeverity को घटाएँ जबकि आप उन्हें मेट्रिक्स में गिनते रहें।

मेट्रिक्स समस्याओं को लॉग से पहले पकड़ लेते हैं। HTTP स्टेटस और एरर कोड द्वारा समूहित काउंट ट्रैक करें, और अचानक spikes पर अलर्ट बनाएं। अगर RATE_LIMITED deploy के बाद 10x बढ़ता है, तो आप इसे जल्दी देख लेंगे भले ही लॉग सैंपलिंग हो।

कदम दर कदम: Go में एक सुसंगत एरर पाइपलाइन लागू करना

कोड से डिप्लॉय तक जाएँ
अपनी सर्विस डिप्लॉय करें और विभिन्न परिवेशों में त्रुटि प्रतिक्रियाएँ सुसंगत रखें।
ऐप डिप्लॉय करें

सबसे आसान तरीका है कि आप हर जगह एरर हैंडलिंग रोक दें और उन्हें एक छोटे पाइपलाइन से गुज़ारें। वह पाइपलाइन तय करती है कि क्लाइंट को क्या दिखे और आप लॉग में क्या रखें।

पाइपलाइन के 5 व्यावहारिक कदम

एक छोटे एरर कोड सेट से शुरू करें जिन पर क्लाइंट भरोसा कर सके (उदाहरण: INVALID_ARGUMENT, NOT_FOUND, UNAUTHORIZED, CONFLICT, INTERNAL)। इन्हें एक टाइप्ड एरर में रैप करें जो केवल सुरक्षित, सार्वजनिक फ़ील्ड्स (code, safe message, वैकल्पिक details जैसे कौन-सा फ़ील्ड गलत है) एक्सपोज़ करे। आंतरिक कारण private रखें।

फिर एक ट्रांसलेटर फ़ंक्शन लागू करें जो किसी भी एरर को (statusCode, responseBody) में बदल दे। यह वही जगह है जहाँ टाइप्ड एरर HTTP स्टेटस को मैप करेंगे, और अज्ञात एरर्स एक सुरक्षित 500 रेस्पॉन्स बन जाएँगे।

अगला, मिडलवेयर जोड़ें जो कि:

  • सुनिश्चित करे कि हर रिक्वेस्ट के पास एक request_id हो
  • panic से recover करे

एक panic कभी क्लाइंट को स्टैक ट्रेस नहीं दिखानी चाहिए। सामान्य 500 रेस्पॉन्स लौटाएँ एक सामान्य संदेश के साथ, और उसी request_id के साथ पूर्ण panic लॉग करें।

अंत में, अपने हैंडलर्स को इस तरह बदलें कि वे सीधे response लिखने के बजाय error रिटर्न करें। एक wrapper हैंडलर इसे कॉल कर सकता है, ट्रांसलेटर चलाकर और मानक फ़ॉर्मेट में JSON लिखकर।

एक सम्मानित चेकलिस्ट:

  • सुरक्षित फ़ील्ड्स और स्थिर कोड्स के साथ टाइप्ड एरर परिभाषित करें।
  • एरर्स को स्टेटस कोड और JSON रेस्पॉन्स में एक जगह पर ट्रांसलेट करें।
  • request ID और panic recovery मिडलवेयर जोड़ें।
  • हैंडलर्स को error लौटाने के लिए बदलें, न कि सीधे रेस्पॉन्स लिखने के लिए।
  • ट्रांसलेटर और wrapper के लिए golden tests जोड़ें।

Golden tests इसलिए महत्वपूर्ण हैं क्योंकि वे कॉन्ट्रैक्ट को लॉक कर देते हैं। अगर कोई बाद में संदेश या स्टेटस बदलता है, तो टेस्ट क्लाइंट्स को चौंकाने से पहले फेल कर देंगे।

उदाहरण: एक एंडपॉइंट, तीन विफलताएँ, पूर्वानुमेय प्रतिक्रियाएँ

कल्पना कीजिए एक एंडपॉइंट: क्लाइंट एप एक कस्टमर रिकॉर्ड बनाता है।

POST /v1/customers JSON जैसे { "email": "[email protected]", "name": "Pat" } के साथ। सर्वर हमेशा वही त्रुटि आकार लौटाता है और हमेशा request_id शामिल होता है।

1) वैलिडेशन एरर (400)

ईमेल गायब है या गलत फ़ॉर्मैट में है। क्लाइंट फ़ील्ड को हाईलाइट कर सके।

{
  "request_id": "req_01HV9N2K6Q7A3W1J9K8B",
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Some fields need attention.",
    "details": {
      "fields": {
        "email": "must be a valid email address"
      }
    }
  }
}

2) कॉन्फ्लिक्ट (409)

ईमेल पहले से मौजूद है। क्लाइंट साइन इन या दूसरा ईमेल चुनने का सुझाव दे सकता है।

{
  "request_id": "req_01HV9N3C2D0F0M3Q7Z9R",
  "error": {
    "code": "ALREADY_EXISTS",
    "message": "A customer with this email already exists."
  }
}

3) अस्थायी विफलता (503)

कोई डिपेंडेंसी डाउन है। क्लाइंट बैकऑफ के साथ retry कर सकता है और एक शांत संदेश दिखा सकता है।

{
  "request_id": "req_01HV9N3X8P2J7T4N6C1D",
  "error": {
    "code": "TEMPORARILY_UNAVAILABLE",
    "message": "We could not save your request right now. Please try again."
  }
}

एक ही कॉन्ट्रैक्ट के साथ, क्लाइंट स्थिर प्रतिक्रिया करता है:

  • 400: details.fields का उपयोग करके फ़ील्ड्स मार्क करें
  • 409: उपयोगकर्ता को सुरक्षित अगले कदम का मार्गदर्शन करें
  • 503: retry का संकेत दें और सपोर्ट ID के तौर पर request_id दिखाएँ

सपोर्ट के लिए, वही request_id आंतरिक लॉग्स में असली कारण तक पहुंचने का सबसे तेज़ रास्ता है, बिना स्टैक ट्रेसेस या डेटाबेस एरर्स को उजागर किए।

आम जाल जो एरर हैंडलिंग को और खराब बनाते हैं

क्लाइंट्स को परेशान करने का तेज़ तरीका है उन्हें अनुमान लगाने पर मजबूर करना। अगर एक एंडपॉइंट { "error": "..." } लौटाए और दूसरा { "message": "..." }, तो हर क्लाइंट स्पेशल केस का ढेर बन जाएगा, और बग हफ्तों तक छिपे रह सकते हैं।

कुछ गलतियाँ बार-बार दिखती हैं:

  • HTTP 200 लौटाते हुए बॉडी में त्रुटि छिपाना, या एंडपॉइंट्स के बीच कई त्रुटि स्कीमों का उपयोग।
  • यूजर संदेश में इंटरनल्स उजागर करना, जैसे SQL एरर्स, स्टैक ट्रेसेस, IPs, डिपेंडेंसी होस्टनेम, या फ़ाइल पाथ।
  • मानवीय टेक्स्ट को ही एकमात्र पहचानकर्ता के रूप में उपयोग करना, बजाय एक स्थिर code के।
  • त्रुटि कोड्स को मनमानी तरीके से बदलना (या एक ही कोड को अलग समस्याओं के लिए पुन: उपयोग करना) और पुराने क्लाइंट्स तोड़ देना।
  • सिर्फ विफलताओं पर request_id जोड़ना, ताकि किसी यूज़र रिपोर्ट को सफल कॉल से correlate नहीं कर सकें जो बाद में समस्या पैदा कर सकता है।

इंटरनल्स लीक करना सबसे आसान जाल है। एक हैंडलर err.Error() लौटाता है क्योंकि यह सुविधाजनक है, और फिर constraint नाम या तृतीय-पक्ष संदेश प्रोडक्शन रिस्पॉन्स में आ जाता है। क्लाइंट संदेश को सुरक्षित और संक्षिप्त रखें, और विस्तृत कारण लॉग्स में रखें।

केवल टेक्स्ट पर निर्भर रहना भी एक धीमी समस्या है। अगर क्लाइंट को अंग्रेज़ी वाक्यों को पार्स करना पड़े जैसे “email already exists,” तो आप wording बदलते ही लॉजिक तोड़ देंगे। स्थिर एरर कोड आपको संदेश समायोजित करने, अनुवाद करने और व्यवहार सुसंगत रखने की अनुमति देते हैं।

एरर कोड्स को अपनी सार्वजनिक कॉन्ट्रैक्ट मानें। अगर आपको किसी कोड को बदलना ही है, तो नया कोड जोड़ें और कुछ समय के लिए पुराना कोड भी काम करता रहे, भले ही दोनों एक ही HTTP स्टेटस को मैप करें।

अंत में, हर उत्तर—सफल या विफल—में वही request_id शामिल करें। जब उपयोगकर्ता कहे "यह काम कर गया, फिर यह टूट गया," वह एक ID अक्सर guessing में एक घंटा बचाती है।

शिप करने से पहले त्वरित चेकलिस्ट

Go API तेजी से बनाएँ
अपना Go API बयान करें और हैंडलर जेनरेट करें जो एक ही त्रुटि उत्तर स्वरूप का पालन करते हैं।
बिल्ड करना शुरू करें

रिलीज़ से पहले एक त्वरित पास:

  • हर जगह एक ही त्रुटि आकार। हर एंडपॉइंट वही JSON फ़ील्ड्स लौटाए (उदाहरण: error.code, error.message, request_id)।
  • स्थिर एरर कोड्स और कवरेज। कोड्स छोटे और स्पष्ट रखें (VALIDATION_FAILED, NOT_FOUND, CONFLICT, UNAUTHORIZED)। टेस्ट रखें ताकि हैंडलर्स गलती से अज्ञात कोड्स न लौटाएँ।
  • एक स्टेटस मैपिंग नियम। तय करें कि हर एरर प्रकार किस HTTP स्टेटस को मैप करेगा, और इसे एक साझा जगह में लागू करें।
  • दोनों दिशाओं में request ID। हर रिक्वेस्ट के लिए request_id लौटाएँ और लॉग भी करें, पैनिक्स और टाइमआउट्स सहित।
  • डिफ़ॉल्ट रूप से सुरक्षित संदेश। यूज़र-फेसिंग संदेश संक्षिप्त, स्पष्ट और कार्रवाईयोग्य होने चाहिए—कभी स्टैक ट्रेसेस, SQL एरर्स, या वेंडर नाम नहीं।

इसके बाद कुछ एंडपॉइंट्स को मैन्युअली स्पॉट-चेक करें। एक वैलिडेशन एरर, एक मिसिंग रिकॉर्ड, और एक अप्रत्याशित विफलता ट्रिगर करें। अगर प्रतिक्रियाएँ एंडपॉइंट्स के बीच अलग दिखती हैं (फ़ील्ड्स बदलते हैं, स्टेटस कोड्स भटकते हैं, संदेश ज़्यादा साझा करते हैं), तो किसी और फीचर जोड़ने से पहले साझा पाइपलाइन को ठीक करें।

एक व्यावहारिक नियम: अगर कोई संदेश हमलावर की मदद करेगा या सामान्य उपयोगकर्ता को भ्रमित करेगा, तो वह लॉग्स में होना चाहिए, रेस्पॉन्स में नहीं।

अगले कदम: अभी मानकीकृत करें और बाद में सुसंगत रखें

अपनी पसंद की त्रुटि कॉन्ट्रैक्ट लिखें जिसे हर एंडपॉइंट फॉलो करे, भले ही आपकी API पहले से लाइव हो। एक साझा कॉन्ट्रैक्ट (स्टेटस, स्थिर एरर कोड, सुरक्षित संदेश, और request_id) क्लाइंट्स के लिए त्रुटियों को पूर्वानुमेय बनाने का सबसे तेज़ तरीका है।

फिर धीरे-धीरे माइग्रेट करें। मौजूदा हैंडलर्स रखें, पर उनकी विफलताओं को एक मैपर के माध्यम से रूट करें जो आंतरिक एरर्स को आपकी सार्वजनिक प्रतिक्रिया आकार में बदल दे। यह जोखिमभरे बड़े रिफैक्टर के बिना सुसंगतता सुधारता है और नए एंडपॉइंट्स को नए फ़ॉर्मैट बनाने से रोकता है।

एक छोटा एरर कोड कैटलॉग रखें और इसे API का हिस्सा समझें। जब कोई नया कोड जोड़ना चाहे, तो एक त्वरित समीक्षा करें: क्या यह वाकई नया है, नाम स्पष्ट है, और क्या यह सही HTTP स्टेटस से मैप होता है?

कुछ परीक्षण जोड़ें जो ड्रिफ्ट पकड़ें:

  • हर त्रुटि उत्तर में request_id शामिल हो।
  • स्टेटस कोड एरर प्रकार से मेल खाता हो (एरर टेक्स्ट से नहीं)।
  • error.code मौजूद हो और कैटलॉग का हिस्सा हो।
  • error.message सुरक्षित हो और कभी भी आंतरिक विवरण न दिखाए।
  • अज्ञात त्रुटियाँ 500 पर generic संदेश के साथ fallback हों।

अगर आप शून्य से Go बैकएंड बना रहे हैं, तो कॉन्ट्रैक्ट जल्दी लॉक कर देना मददगार हो सकता है। उदाहरण के लिए, Koder.ai (koder.ai) में एक planning mode है जहाँ आप upfront ऐसी conventions जैसे त्रुटि स्कीमा और कोड कैटलॉग परिभाषित कर सकते हैं, फिर API बढ़ने के साथ हैंडलर्स को aligned रख सकते हैं।

अक्सर पूछे जाने वाले प्रश्न

“सुसंगत त्रुटि उत्तर” कैसा दिखना चाहिए?

हर त्रुटि उत्तर के लिए एक ही JSON आकार उपयोग करें, सभी एंडपॉइंट्स पर। एक व्यावहारिक डिफ़ॉल्ट है शीर्ष-स्तर request_id और एक error ऑब्जेक्ट जिसमें code, message, और वैकल्पिक details हों—ताकि क्लाइंट विश्वसनीय रूप से पार्स और प्रतिक्रिया दे सकें।

API त्रुटियों में आंतरिक विवरण लीक होने से कैसे बचें?

उपयोगकर्ता सुरक्षित, संक्षिप्त वाक्य के रूप में error.message लौटाएँ और वास्तविक कारण सर्वर लॉग में रखें। कच्चे डेटाबेस त्रुटियाँ, स्टैक ट्रेस, आंतरिक होस्टनाम या अन्य डिपेंडेंसी संदेश कभी न भेजें, भले ही विकास के समय वे सहायक लगें।

क्या मुझे वास्तव में HTTP स्टेटस होने पर भी एक error code चाहिए?

HTTP स्टेटस कैटेगरी बताता है, पर मशीन-लॉजिक के लिए एक स्थिर error.code जरूरी है। क्लाइंट्स को error.code (जैसे ALREADY_EXISTS) पर शाखा बनानी चाहिए और स्थिति को व्यापक मार्गदर्शक की तरह लेना चाहिए (जैसे 409 एक state conflict को दर्शाता है)।

कब HTTP 400 बनाम 422 का उपयोग करना चाहिए?

जब रिक्वेस्ट विश्वसनीय रूप से पार्स न हो सके (बिगड़ा JSON, गलत प्रकार), तो 400 का उपयोग करें। जब रिक्वेस्ट सही ढंग से पार्स हो लेकिन व्यापार नियमों पर खरा न उतरे (अमान्य ईमेल, पासवर्ड छोटा), तब 422 का उपयोग करें।

कब HTTP 409 बनाम 422 का उपयोग करना चाहिए?

409 का उपयोग तब करें जब इनपुट वैध हो पर वर्तमान स्टेट से टकराता हो (ईमेल पहले से मौजूद, वर्शन मिसमैच)। 422 फील्ड-स्तर वैलिडेशन के लिए है जहाँ मान बदलने से समस्या सुलझ जाती है बिना सर्वर स्टेट को बदलने की।

Go में टाइप्ड एरर कैसे प्रतिक्रियाएँ सुसंगत रखने में मदद करते हैं?

एक छोटी सेट टाइप्ड एरर बनाएं (validation, not found, conflict, unauthorized, internal) और हैंडलर्स इन्हें रिटर्न करें। फिर एक साझा ट्रांसलेटर इन प्रकारों को स्टेटस कोड और मानक JSON उत्तर में मैप करे—इससे प्रतिक्रियाएँ सुसंगत रहती हैं।

मुझे request IDs कैसे जेनरेट और लौटाने चाहिए?

हर उत्तर में request_id लौटाएँ, सफल या विफल—और हर सर्वर लॉग लाइन पर इसे लॉग करें। क्लाइंट कोई समस्या रिपोर्ट करे तो वही ID अक्सर सही लॉग एंट्री तक पहुंचने के लिए काफी होता है।

HTTP 200 के साथ `{ "ok": false }` लौटाना क्यों बुरा विचार है?

सिर्फ़ { "ok": false } के साथ HTTP 200 लौटाना गलत है। 200 केवल तब लौटाएँ जब ऑपरेशन सफल हो; त्रुटियों के लिए 4xx/5xx उपयोग करें। 200 के पीछे त्रुटियाँ छिपाने से क्लाइंट्स को बॉडी फ़ील्ड्स पार्स करने पर मजबूर होना पड़ता है और व्यवहार असंगत होता है।

कौन सी त्रुटियों के लिए क्लाइंट्स retry करें और कौन सी के लिए नहीं?

सामान्यतः 400, 401, 403, 404, 409 और 422 के लिए बिना बदलाव के retry न करें क्योंकि retry से मदद नहीं मिलेगी। 503 के लिए retry करें, और कभी-कभी 429 के लिए भी (थोड़ी देर बाद); अगर आप idempotency keys सपोर्ट करते हैं तो ट्रांज़िएंट फेलियर पर POST के लिए retries सुरक्षित बनती हैं।

API विकसित होते समय त्रुटि प्रतिक्रियाएँ ड्रिफ्ट होने से कैसे रोका जाए?

कुछ “गोल्डन” टेस्ट रखें जो सुनिश्चित करें: हर त्रुटि उत्तर में request_id हो; स्टेटस कोड एरर प्रकार से मेल खाता हो; error.code कैटलॉग से हो; error.message सुरक्षित हो; और अज्ञात त्रुटियाँ 500 पर generic संदेश के साथ fallback हों। इससे विकसित होते समय उत्तरों के ड्रिफ्ट होने से बचाव होगा।

विषय-सूची
असंगत API त्रुटियाँ क्लाइंट्स को क्यों परेशान करती हैंएक सरल लक्ष्य: हर एंडपॉइंट एक ही कॉन्ट्रैक्ट फॉलो करेएक ऐसा त्रुटि उत्तर स्कीमा परिभाषित करें जिस पर क्लाइंट भरोसा कर सकेंGo में टाइप्ड एरर: आपके हैंडलर्स के लिए एक साफ मॉडलएरर प्रकारों को HTTP स्टेटस कोड्स पर सुसंगत रूप से मैप करेंRequest IDs: क्लाइंट मुद्दों को डिबग करने का सबसे तेज़ तरीकाइंटरनल्स लीक किए बिना लॉगिंग और मेट्रिक्सकदम दर कदम: Go में एक सुसंगत एरर पाइपलाइन लागू करनाउदाहरण: एक एंडपॉइंट, तीन विफलताएँ, पूर्वानुमेय प्रतिक्रियाएँआम जाल जो एरर हैंडलिंग को और खराब बनाते हैंशिप करने से पहले त्वरित चेकलिस्टअगले कदम: अभी मानकीकृत करें और बाद में सुसंगत रखेंअक्सर पूछे जाने वाले प्रश्न
शेयर करें
Koder.ai
Koder के साथ अपना खुद का ऐप बनाएं आज ही!

Koder की शक्ति को समझने का सबसे अच्छा तरीका खुद देखना है।

मुफ्त शुरू करेंडेमो बुक करें