स्पष्ट, मानव-अनुकूल संदेशों के लिए API त्रुटि अनुबंध पैटर्न
स्थिर कोड, स्थानीयकृत संदेश और UI-अनुकूल संकेतों वाले API त्रुटि अनुबंध को डिजाइन करें जो सपोर्ट का बोझ घटाएं और उपयोगकर्ताओं को तेज़ी से पुनर्प्राप्त करने में मदद करें।

अस्पष्ट API त्रुटियाँ असल में उपयोगकर्ताओं के लिए क्या समस्याएँ बनाती हैं
एक अस्पष्ट API त्रुटि सिर्फ एक तकनीकी झंझट नहीं है। यह प्रोडक्ट में एक टूटा हुआ पल होता है जहाँ कोई फंस जाता है, अनुमान लगाता है कि आगे क्या करना है, और अक्सर हिम्मत हार देता है। वह एकल "कुछ गलत हुआ" और अधिक सपोर्ट टिकट, churn, और ऐसे बग्स में बदल जाता है जो कभी पूरी तरह सुलझते नहीं दिखते।
एक सामान्य पैटर्न ऐसा दिखता है: यूज़र एक फॉर्म सेव करने की कोशिश करता है, UI एक सामान्य टोस्ट दिखाता है, और बैकएंड लॉग असली कारण दिखाते हैं ("unique constraint violation on email")। उपयोगकर्ता नहीं जानता कि क्या बदलना है। सपोर्ट मदद नहीं कर पाता क्योंकि खोजने के लिए कोई भरोसेमंद कोड नहीं है। वही समस्या अलग-अलग स्क्रीनशॉट और शब्दों के साथ बार-बार रिपोर्ट होती है, और उसे समूहित करने का साफ़ तरीका नहीं होता।
डेवलपर का विवरण और उपयोगकर्ता की ज़रूरतें एक जैसी नहीं होतीं। इंजीनियरों को सटीक फेलियर कॉन्टेक्स्ट चाहिए (कौन सा फील्ड, कौन सी सर्विस, कौन सा टाइमआउट)। उपयोगकर्ताओं को एक स्पष्ट अगला कदम चाहिए: "यह ईमेल पहले से उपयोग में है। साइन इन करने का प्रयास करें या कोई और ईमेल उपयोग करें।" इन दोनों को मिलाना अक्सर या तो असुरक्षित खुलासा (इंटर्नल जानकारी लीक होना) या बेमेल संदेशों (सब कुछ छिपा देना) की ओर ले जाता है।
यही काम API त्रुटि अनुबंध करता है। लक्ष्य "अधिक त्रुटियाँ" नहीं है। यह एक सुसंगत संरचना है ताकि:
- क्लाइंट अलग-अलग endpoints पर असफलताओं को भरोसेमंद तरीके से интерप्रेट कर सकें
- उपयोगकर्ता सुरक्षित, सामान्य भाषा में संदेश देखें जो उन्हें सुधारने में मदद करें
- सपोर्ट और QA सटीक समस्या को एक स्थिर कोड से पहचान सकें
- इंजीनियर संवेदनशील विवरण उजागर किए बिना डायग्नोस्टिक्स पा सकें
सुसंगतता ही पूरा मुद्दा है। अगर एक एंडपॉइंट error: "Invalid" लौटाता है और दूसरा message: "Bad request", तो UI उपयोगकर्ताओं का मार्गदर्शन नहीं कर सकता और आपकी टीम यह माप नहीं सकती कि क्या हो रहा है। एक स्पष्ट अनुबंध त्रुटियों को अनुमान्य, searchable, और सुधारने में आसान बनाता है, भले ही नीचे का कारण बदल जाए।
व्यवहार में एक सुसंगत त्रुटि अनुबंध का मतलब
API त्रुटि अनुबंध एक वादा है: जब कुछ गलत होता है, आपका API किसी परिचित आकार में, अनुमान्य फ़ील्ड और कोड के साथ उत्तर देता है, चाहे कौन सा एन्डपॉइंट फेल हुआ हो।
यह डिबगिंग डंप नहीं है, और न ही लॉग्स का विकल्प। अनुबंध वह है जिस पर क्लाइंट ऐप्स सुरक्षित रूप से निर्भर कर सकते हैं। लॉग्स वह जगह हैं जहाँ आप स्टैक ट्रेसेज़, SQL विवरण, और संवेदनशील चीज़ें रखें।
व्यवहार में, एक ठोस अनुबंध कुछ चीज़ों को स्थिर रखता है: एन्डपॉइंट्स के बीच response shape (4xx और 5xx दोनों के लिए), मशीन-पठनीय स्थिर त्रुटि कोड जो अर्थ नहीं बदलते, और एक सुरक्षित यूज़र-फेसिंग संदेश। यह सपोर्ट के लिए एक request/trace identifier भी शामिल कर सकता है, और यह सरल UI संकेत भी दे सकता है जैसे कि उपयोगकर्ता को रिट्राय करना चाहिए या किसी फील्ड को ठीक करना चाहिए।
सुसंगतता तभी काम करती है जब आप तय करें कि इसे कहाँ लागू किया जाएगा। टीमें अक्सर एक एन्फोर्समेंट पॉइंट से शुरू करती हैं और बाद में बढ़ाती हैं: एक API गेटवे जो त्रुटियों को सामान्य करता है, मिडलवेयर जो uncaught फेलियर्स को रैप करता है, एक साझा लाइब्रेरी जो वही एरर ऑब्जेक्ट बनाती है, या हर सर्विस के लिए फ्रेमवर्क-लेवल एक्सेप्शन हैंडलर।
मुख्य उम्मीद सरल है: हर एंडपॉइंट या तो सफलता का आकार लौटाएगा या हर विफलता मोड के लिए त्रुटि अनुबंध। इसमें वैलिडेशन त्रुटियाँ, ऑथ फेल्यर, रेट लिमिट, टाइमआउट, और अपस्ट्रीम आउटेज शामिल हैं।
एक सरल त्रुटि रिस्पॉन्स आकार जो स्केल करता है
एक अच्छा API त्रुटि अनुबंध छोटा, अनुमान्य, और लोगों और सॉफ़्टवेयर दोनों के लिए उपयोगी रहता है। जब क्लाइंट हमेशा एक ही फ़ील्ड्स खोज पाए, सपोर्ट अनुमान लगाना बंद कर देता है और UI स्पष्ट सहायता दे सकता है।
यहाँ एक न्यूनतम JSON आकार है जो अधिकांश प्रोडक्ट्स के लिए काम करता है (और जैसे-जैसे आप अधिक एंडपॉइंट जोड़ते हैं, स्केल करता है):
{
\"status\": 400,
\"code\": \"AUTH.INVALID_EMAIL\",
\"message\": \"Enter a valid email address.\",
\"details\": {
\"fields\": {
\"email\": \"invalid_email\"
},
\"action\": \"fix_input\",
\"retryable\": false
},
\"trace_id\": \"01HZYX8K9Q2...\"
}
अनुबंध को स्थिर रखने के लिए, हर हिस्से को अलग वादा मानें:
statusHTTP व्यवहार और व्यापक श्रेणियों के लिए है।codeस्थिर, मशीन-पठनीय पहचानकर्ता है (आपके API त्रुटि अनुबंध का मूल)।messageसुरक्षित UI टेक्स्ट है (और बाद में आप इसे स्थानीयकृत कर सकते हैं)।detailsसंरचित संकेत रखता है: फील्ड-स्तर समस्याएं, अगला कदम क्या है, और क्या रिट्राय करना ठीक है।trace_idसपोर्ट को सटीक सर्वर-साइड विफलता खोजने देता है बिना आंतरिक बातें उजागर किये।
यूज़र-फेस सामग्री को आंतरिक डिबग जानकारी से अलग रखें। अगर आपको अतिरिक्त डायग्नोस्टिक्स चाहिए, तो उन्हें सर्वर-साइड पर trace_id के साथ लॉग करें (रिस्पॉन्स में नहीं)। इससे संवेदनशील डेटा लीक होने से बचता है और मुद्दों को जल्दी खोजने में मदद मिलती है।
फील्ड त्रुटियों के लिए, details.fields एक सरल पैटर्न है: कीज़ इनपुट नामों से मेल खाती हैं, मान छोटे कारण रखते हैं जैसे invalid_email या too_short। केवल तभी मार्गदर्शन जोड़ें जब यह मददगार हो। टाइमआउट के लिए, action: "retry_later" काफी है। अस्थायी आउटेज के लिए, retryable: true क्लाइंट्स को तय करने में मदद करता है कि क्या रिट्राय बटन दिखाना चाहिए।
एक नोट पहले कि आप लागू करें: कुछ टीमें त्रुटियों को error ऑब्जेक्ट में रैप करती हैं (उदाहरण: { \"error\": { ... } }) जबकि अन्य फील्ड्स को ऊपर रखते हैं। दोनों ही तरीके काम कर सकते हैं। जो मायने रखता है वह यह है कि आप एक एनवेलप चुनें और हर जगह सुसंगत रहें।
स्थिर त्रुटि कोड: ऐसे पैटर्न जो क्लाइंट्स को ब्रेक नहीं करते
स्थिर त्रुटि कोड API त्रुटि अनुबंध की रीढ़ हैं। वे ऐप्स, डैशबोर्ड, और सपोर्ट टीमों को एक समस्या पहचानने देते हैं भले ही आप वर्डिंग बदलें, फील्ड जोड़ें, या UI बेहतर करें।
एक व्यावहारिक नामकरण परंपरा है:
DOMAIN.ACTION.REASON
उदाहरण: AUTH.LOGIN.INVALID_PASSWORD, BILLING.PAYMENT.CARD_DECLINED, PROFILE.UPDATE.EMAIL_TAKEN। डोमेनों को छोटा और परिचित रखें (AUTH, BILLING, FILES)। क्रिया क्रियावाचक रूपों का उपयोग करें जो स्पष्ट पढ़ें (CREATE, UPDATE, PAY)।
कोड्स को एंडपॉइंट्स की तरह मानें: एक बार सार्वजनिक होने के बाद, उनके अर्थ नहीं बदलने चाहिए। उपयोगकर्ता को दिखने वाला टेक्स्ट समय के साथ बेहतर हो सकता है (बेहतर टोन, स्पष्ट कदम, नई भाषाएँ), लेकिन कोड वही रहना चाहिए ताकि क्लाइंट्स न टूटें और एनालिटिक्स साफ़ रहे।
यह तय करना भी फायदेमंद है कि कौन से कोड सार्वजनिक हैं और कौन से केवल आंतरिक। एक सरल नियम: सार्वजनिक कोड सुरक्षित तरीके से दिखाने योग्य, स्थिर, दस्तावेजीकृत, और UI द्वारा उपयोग किए जाने योग्य होने चाहिए। आंतरिक कोड्स लॉग्स में डिबग के लिए रहें (डेटाबेस नाम, वेंडर विवरण, स्टैक इत्यादि)। एक सार्वजनिक कोड कई आंतरिक कारणों से मैप हो सकता है, खासकर जब एक डिपेंडेंसी कई तरह से फेल हो सकती है।
डिप्रिकेशन सबसे अच्छा तब काम करता है जब यह उबाऊ हो। अगर आपको कोई कोड बदलना ही पड़े, तो इसे मौन रूप से नया मतलब न दें। एक नया कोड पेश करें और पुराने को डिप्रिकेटेड मार्क करें। क्लाइंट्स को ओवरलैप विंडो दें जहाँ दोनों रूप मिल सकते हैं। अगर आप deprecated_by जैसा फ़ील्ड शामिल करते हैं, तो वह नए कोड की ओर इशारा करे (URL नहीं)।
उदाहरण के लिए, BILLING.PAYMENT.CARD_DECLINED रखें भले ही आप बाद में UI कॉपी सुधारें और इसे "दूसरा कार्ड आज़माएँ" बनाम "अपने बैंक से बात करें" में विभाजित करें। कोड स्थिर रहता है जबकि मार्गदर्शन बदलता है।
स्थानीयकृत संदेश बिना सुसंगतता खोए
जब API पूर्ण वाक्य लौटाता है और क्लाइंट्स उन्हें लॉजिक की तरह ट्रीट करते हैं, तब लोकलाइजेशन गड़बड़ हो जाता है। एक बेहतर तरीका यह है कि अनुबंध को स्थिर रखें और "last-mile" टेक्स्ट का अनुवाद क्लाइंट-साइड या नियंत्रित स्रोत पर करें। इस तरह वही त्रुटि हर भाषा, डिवाइस या ऐप वर्शन में एक ही अर्थ रखती है।
सबसे पहले तय करें कि अनुवाद कहाँ रहेंगे। अगर आपको वेब, मोबाइल और सपोर्ट टूल्स के बीच एक सोर्स-ऑफ-ट्रुथ चाहिए, तो सर्वर-साइड संदेश मदद कर सकते हैं। अगर UI को टोन और लेआउट पर कड़ा नियंत्रण चाहिए, तो क्लाइंट-साइड अनुवाद अक्सर आसान रहते हैं। कई टीमें हाइब्रिड का उपयोग करती हैं: API एक स्थिर कोड प्लस एक संदेश कुंजी और पैरामीटर लौटाती है, और क्लाइंट सर्वश्रेष्ठ डिस्प्ले टेक्स्ट चुनकर फॉर्मेट करता है।
API त्रुटि अनुबंध के लिए, संदेश कुंजियाँ आमतौर पर हार्डकोर्ड वाक्यों से सुरक्षित होती हैं। API कुछ इस तरह लौट सकता है: message_key: "auth.too_many_attempts" और params: {"retry_after_seconds": 300}। UI इसे ट्रांसलेट और फॉर्मेट करे बिना अर्थ बदलते हुए।
Pluralization और fallbacks की ज़रूरत की अपेक्षा से अधिक होती है। प्रत्येक locale के लिए plural नियम सपोर्ट करने वाला i18n सेटअप इस्तेमाल करें, सिर्फ अंग्रेज़ी-स्टाइल "1 बनाम कई" नहीं। एक fallback चैन परिभाषित करें (उदाहरण: fr-CA -> fr -> en) ताकि गायब स्ट्रिंग्स खाली स्क्रीन में न बदलें।
एक अच्छा गार्डरेल यह है कि अनुवादित टेक्स्ट को सख़्ती से यूज़र-फेसिंग मानें। स्टैक ट्रेस, आंतरिक IDs, या कच्चा "क्यों फेल हुआ" विवरण लोकलाइज़्ड स्ट्रिंग्स में न डालें। संवेदनशील विवरण को न-डिस्प्ले फील्ड्स में रखें (या लॉग्स में) और उपयोगकर्ताओं को सुरक्षित, क्रियाशील शब्दावली दें।
बैकएंड विफलताओं को UI संकेतों में बदलना जो उपयोगकर्ता फॉलो कर सकें
अधिकतर बैकएंड त्रुटियाँ इंजीनियरों के लिए उपयोगी होती हैं, पर अक्सर वे स्क्रीन पर "कुछ गलत हुआ" के रूप में आ जाती हैं। एक अच्छा त्रुटि अनुबंध विफलताओं को स्पष्ट अगले कदमों में बदल देता है बिना संवेदनशील विवरण लीक किए।
एक सरल तरीका विफलताओं को तीन उपयोगकर्ता क्रियाओं में मैप करना है: इनपुट सुधारें, पुनः प्रयास करें, या सपोर्ट से संपर्क करें। इससे UI वेब और मोबाइल पर सुसंगत रहता है भले ही बैकएंड के कई विफलता मोड हों।
- इनपुट सुधारें: वैलिडेशन फेल, फॉर्मैट गलत, आवश्यक फील्ड गायब।
- पुनः प्रयास करें: टाइमआउट, अस्थायी अपस्ट्रीम समस्याएँ, रेट लिमिट।
- सपोर्ट से संपर्क करें: अनुमति संबंधी समस्याएँ, कनफ्लिक्ट्स जिन्हें उपयोगकर्ता हल नहीं कर सकता, अप्रत्याशित आंतरिक त्रुटियाँ।
फील्ड संकेत लंबे संदेशों से ज़्यादा असर रखते हैं। जब बैकएंड जानता है कि कौन सा इनपुट फेल हुआ, तो मशीन-पठनीय पॉइंटर लौटाएँ (उदाहरण के लिए, फील्ड नाम जैसे email या card_number) और एक छोटा कारण जो UI इनलाइन दिखा सके। अगर कई फील्ड्स गलत हैं, तो सभी लौटाएँ ताकि उपयोगकर्ता एक बार में सब सुधार सके।
यह भी मदद करता है कि UI पैटर्न स्थिति के अनुकूल हो। एक टोस्ट अस्थायी रिट्राय संदेश के लिए ठीक है। इनपुट त्रुटियाँ इनलाइन हों। अकाउंट और पेमेंट ब्लॉकर्स आमतौर पर ब्लॉकिंग डायलॉग मांगते हैं।
सुरक्षित ट्रबलशूटिंग कॉन्टेक्स्ट को लगातार शामिल करें: trace_id, एक टाइमस्टैम्प अगर आपके पास पहले से है, और सुझाया गया अगला कदम जैसे रिट्राय विलंब। इस तरह एक पेमेंट प्रोवाइडर टाइमआउट दिखा सकता है "पेमेन्ट सर्विस धीमी है। कृपया बाद में फिर कोशिश करें" साथ में रिट्राय बटन, जबकि सपोर्ट वही trace_id इस्तेमाल करके सर्वर-साइड विफलता ढूँढ सकता है।
चरण-दर-चरण: अनुबंध को एंड-टू-एंड रोल आउट करना
API त्रुटि अनुबंध को रोल आउट करना तब सबसे अच्छा होता है जब आप इसे एक छोटे प्रोडक्ट चेंज की तरह ट्रीट करें, न कि सिर्फ एक रिफैक्टर। इसे क्रमिक रखें, और सपोर्ट और UI टीमों को जल्दी शामिल करें।
एक रोलआउट अनुक्रम जो यूज़र-फेसिंग संदेशों को जल्दी बेहतर बनाये बिना क्लाइंट्स को तोड़े:
- जो अब है उसकी इन्वेंटरी लें (डोमेन के हिसाब से समूहित)। लॉग्स से वास्तविक त्रुटि रिस्पॉन्स एक्सपोर्ट करें और उन्हें auth, signup, billing, file upload, permissions जैसे बकेट्स में ग्रुप करें। दोहराव, अस्पष्ट संदेश, और जगहें ढूँढें जहाँ एक ही विफलता पाँच अलग शेप में आती है।
- स्कीमा परिभाषित करें और उदाहरण साझा करें। रिस्पॉन्स शेप, आवश्यक फ़ील्ड्स, और डोमेन-वार उदाहरण दस्तावेज़ करें। स्थिर कोड नाम, लोकलाइजेशन के लिए एक संदेश कुंजी, और UI के लिए एक वैकल्पिक hint सेक्शन शामिल करें।
- एक केंद्रीय एरर मैपर लागू करें। फॉर्मैटिंग एक ही जगह रखें ताकि हर एन्डपॉइंट एक ही संरचना लौटाए। जनरेटेड बैकएंड में (या कोई-नो-कोड बैकएंड में), इसका मतलब अक्सर एक साझा "map error to response" स्टेप है जिसे हर एंडपॉइंट या बिजनेस प्रोसेस कॉल करता है।
- UI को कोड्स इंटरप्रेट करने के लिए अपडेट करें और hints दिखाएँ। UI को टेक्स्ट पर निर्भर करने के बजाय कोड्स पर निर्भर बनाएं। कोड्स से तय करें कि फील्ड को हाईलाइट करना है, रिट्राय्शन दिखानी है, या सपोर्ट से संपर्क सुझाना है।
- लॉगिंग और trace_id जोड़ें जिससे सपोर्ट पूछ सके। हर रिक्वेस्ट के लिए trace_id जनरेट करें, इसे सर्वर-साइड कच्ची विफलता डिटेल्स के साथ लॉग करें, और इसे एरर रिस्पॉन्स में लौटाएँ ताकि उपयोगकर्ता इसे कॉपी कर सकें।
पहले पास के बाद, अनुबंध को स्थिर रखने के लिए कुछ हल्के-फुल्के artifacts रखें: डोमेन-वार त्रुटि कोड्स का साझा कैटलॉग, लोकलाइजेशन फाइल्स, कोड -> UI hint/next action मैपिंग की एक सरल टेबल, और एक सपोर्ट प्लेबुक जो "हमें अपना trace_id भेजें" से शुरू हो।
अगर आपके पास लेगेसी क्लाइंट्स हैं, तो एक छोटी डिप्रिकेशन विंडो के लिए पुराने फ़ील्ड रखें, पर नए वन-ऑफ शेप्स बनाना तुरंत बंद कर दें।
आम गलतियाँ जो त्रुटियों को सपोर्ट करने में कठिन बनाती हैं
ज़्यादातर सपोर्ट की दिक्कतें "बेड यूज़र्स" से नहीं आतीं। वे अस्पष्टता से आती हैं। जब आपका API त्रुटि अनुबंध असंगत होता है, तो हर टीम अपनी व्याख्या बना लेती है, और उपयोगकर्ताओं को ऐसे संदेश मिलते हैं जिन पर वे कार्रवाई नहीं कर सकते।
एक आम जाल HTTP स्टेटस को पूरे कथानक की तरह मान लेना है। "400" या "500" यह नहीं बताता कि उपयोगकर्ता आगे क्या करे। स्टेटस कोड ट्रांसपोर्ट और व्यापक वर्गीकरण में मदद करते हैं, पर आपको एक स्थिर, ऐप-लैवल कोड की ज़रूरत होती है जिसका अर्थ वर्शन के पार भी वही रहे।
एक और गलती है किसी कोड का अर्थ समय के साथ बदलना। अगर PAYMENT_FAILED पहले "कार्ड अस्वीकृत" मतलब देता था और बाद में इसका अर्थ "Stripe डाउन है" हो जाए, तो आपका UI और डॉक गलत हो जाएंगे बिना किसी को पता चले। सपोर्ट फिर ऐसे टिकट पाएगा जैसे "मैंने तीन कार्ड आज़माये और फिर भी फेल हुआ" जबकि असली मुद्दा आउटेज है।
कच्चा exception टेक्स्ट (या उससे भी बदतर, स्टैक ट्रेस) लौटाना भी लुभावना होता है क्योंकि यह जल्दी होता है। यह उपयोगकर्ताओं के लिए सहायक नहीं होता और संवेदनशील जानकारी लीक कर सकता है। कच्चा डायग्नोस्टिक्स लॉग्स में रखें, न कि रिस्पॉन्स में।
कुछ पैटर्न लगातार शोर पैदा करते हैं:
UNKNOWN_ERRORजैसे catch-all कोड का अधिक उपयोग किसी भी मार्गदर्शन की संभावना समाप्त कर देता है।- बिना स्पष्ट टैक्सोनॉमी के बहुत सारे कोड बनाना डैशबोर्ड और प्लेबुक को बनाए रखना मुश्किल कर देता है।
- उपयोगकर्ता-मुखी टेक्स्ट और डेवलपर डायग्नोस्टिक्स को एक ही फ़ील्ड में मिलाना लोकलाइजेशन और UI संकेतों को नाज़ुक बनाता है।
एक सरल नियम मददगार है: हर उपयोगकर्ता निर्णय के लिए एक स्थिर कोड। अगर उपयोगकर्ता इसे इनपुट बदलकर ठीक कर सकता है, तो एक विशिष्ट कोड और स्पष्ट hint दें। अगर वह नहीं कर सकता (जैसे प्रदाता आउटेज), तो कोड स्थिर रखें और सुरक्षित संदेश लौटाएँ साथ में "बाद में फिर कोशिश करें" जैसी क्रिया और सपोर्ट के लिए correlation ID।
त्वरित प्री-रिलीज चेकलिस्ट
शिप करने से पहले त्रुटियों को एक प्रोडक्ट फीचर की तरह ट्रीट करें। जब कुछ फेल हो, उपयोगकर्ता को अगले कदम का पता होना चाहिए, सपोर्ट को सटीक ईवेंट मिल सके, और क्लाइंट्स बैकएंड बदलने पर न टूटें।
- हर जगह एक ही आकार: हर एंडपॉइंट (auth, webhooks, file uploads सहित) एक सुसंगत त्रुटि एनवेलप लौटाता है।
- स्थिर, मालिक वाले कोड: हर कोड का स्पष्ट मालिक हो (Payments, Auth, Billing)। किसी कोड को अलग अर्थ के लिए फिर से उपयोग न करें।
- सुरक्षित, लोकलाइज़ेबल संदेश: उपयोगकर्ता-फेसिंग टेक्स्ट छोटा और कभी भी सीक्रेट्स (टोकन, पूरा कार्ड डेटा, कच्चा SQL, स्टैक ट्रेस) शामिल न करे।
- स्पष्ट UI अगली क्रिया: शीर्ष विफलता प्रकारों के लिए UI एक स्पष्ट अगला कदम दिखाए (फिर से कोशिश करें, फ़ील्ड अपडेट करें, अलग भुगतान विधि उपयोग करें, सपोर्ट से संपर्क करें)।
- सपोर्ट के लिए ट्रेसबिलिटी: हर एरर रिस्पॉन्स में
trace_id(या समकक्ष) शामिल हो जिसे सपोर्ट मांग सके, और आपके लॉगिंग/मॉनिटरिंग से पूरा विवरण तुरंत मिल सके।
कौन से realistic flows end-to-end टेस्ट करें: एक फॉर्म जिसमें इनवैलिड इनपुट हो, एक एक्स्पायर्ड सेशन, एक रेट लिमिट, और एक थर्ड-पार्टी आउटेज। अगर आप विफलता को एक वाक्य में समझा नहीं पा रहे और लॉग में वही trace_id दिखाकर नहीं ढूँढ सकते, तो आप शिप करने के लिए तैयार नहीं हैं।
उदाहरण: साइनअप और पेमेंट विफलताएँ जिनसे उपयोगकर्ता उबर सकें
एक अच्छा API त्रुटि अनुबंध वही विफलता तीन जगहों पर समझने योग्य बनाता है: आपकी वेब UI, मोबाइल ऐप, और वह स्वचालित ईमेल जो आपके सिस्टम ने फेल्ड प्रयास के बाद भेजा होगा। यह सपोर्ट को बिना स्क्रीनशॉट माँगे पर्याप्त विवरण भी देता है।
साइनअप: ऐसी वैलिडेशन त्रुटि जिसे उपयोगकर्ता ठीक कर सके
एक उपयोगकर्ता sam@ जैसा ईमेल डालता है और Sign up टैप करता है। API एक स्थिर कोड और फील्ड-स्तर hint लौटाता है, ताकि हर क्लाइंट वही फील्ड हाईलाइट करे।
{
\"error\": {
\"code\": \"AUTH.EMAIL_INVALID\",
\"message\": \"Enter a valid email address.\",
\"i18n_key\": \"auth.email_invalid\",
\"params\": { \"field\": \"email\" },
\"ui\": { \"field\": \"email\", \"action\": \"focus\" },
\"trace_id\": \"4f2c1d...\"
}
}
वेब पर, आप संदेश ईमेल बॉक्स के नीचे दिखाते हैं। मोबाइल पर, आप ईमेल फील्ड पर फोकस कराते हैं और एक छोटा बैनर दिखाते हैं। ईमेल में आप कह सकते हैं: "हम आपका अकाउंट नहीं बना पाए क्योंकि ईमेल पता अधूरा दिखता है।" वही कोड, वही अर्थ।
पेमेंट: उपयोगकर्ता को सुरक्षित व्याख्या के साथ विफलता
एक कार्ड पेमेंट फेल हो जाता है। उपयोगकर्ता को मार्गदर्शन चाहिए, पर प्रोसेसर इंटरनल्स उजागर नहीं करने चाहिए। आपका अनुबंध उपयोगकर्ता को जो दिखे और सपोर्ट जो सत्यापित करे उसे अलग कर सकता है।
{
\"error\": {
\"code\": \"PAYMENT.DECLINED\",
\"message\": \"Your payment was declined. Try another card or contact your bank.\",
\"i18n_key\": \"payment.declined\",
\"params\": { \"retry_after_sec\": 0 },
\"ui\": { \"action\": \"show_payment_methods\" },
\"trace_id\": \"b9a0e3...\"
}
}
सपोर्ट trace_id पूछ सकता है, फिर यह सत्यापित कर सकता है कि कौन सा स्थिर कोड लौटाया गया था, decline final है या retryable, किस अकाउंट और राशि के लिए प्रयास था, और क्या UI hint भेजा गया था।
यही वह जगह है जहाँ API त्रुटि अनुबंध का लाभ मिलता है: आपकी वेब, iOS/Android और ईमेल फ्लो एक समान रहते हैं भले ही बैकएंड प्रोवाइडर या आंतरिक विफलता विवरण बदलें।
अपने त्रुटि अनुबंध का समय के साथ परीक्षण और मॉनिटरिंग
API त्रुटि अनुबंध तब "किया गया" नहीं माना जाता जब यह शिप हो। यह तब "किया गया" माना जाता है जब वही त्रुटि कोड महीनों बाद भी एक ही उपयोगकर्ता कार्रवाई की ओर ले जाए, भले ही रिफैक्टर्स और नई फ़ीचर आए हों।
बाहरी तौर पर, एक वास्तविक क्लाइंट की तरह टेस्टिंग से शुरू करें। हर एरर कोड के लिए कम से कम एक रिक्वेस्ट लिखें जो उसे ट्रिगर करे और उस व्यवहार का asserts रखें जिस पर आप वास्तव में निर्भर करते हैं: HTTP स्टेटस, कोड, लोकलाइज़ेशन की- और UI hint फ़ील्ड्स (जैसे कौन सा फॉर्म फील्ड हाईलाइट करना है)।
एक छोटा टेस्ट सेट अधिकांश जोखिम को कवर करता है:
- हर एरर केस के पास एक हैप्पी-पाथ रिक्वेस्ट (अत्यधिक वैलिडेशन पकड़ने के लिए)
- हर स्थिर कोड के लिए एक टेस्ट जो लौटाए गए UI hints या फील्ड मैपिंग की जाँच करे
- एक टेस्ट जो सुनिश्चित करे कि अज्ञात विफलताएँ एक सुरक्षित सामान्य कोड लौटाती हैं
- एक टेस्ट जो सुनिश्चित करे कि प्रत्येक समर्थित भाषा के लिए लोकलाइज़ेशन कीज़ मौजूद हैं
- एक टेस्ट जो यह सुनिश्चित करे कि संवेदनशील विवरण कभी क्लाइंट रिस्पॉन्स में नहीं आते
मॉनिटरिंग उन regressions को पकड़ने का तरीका है जिन्हें टेस्ट मिस कर देते हैं। त्रुटि कोड्स की संख्या समय के साथ ट्रैक करें और अचानक स्पाइक्स पर अलर्ट सेट करें (उदाहरण: किसी रिलीज़ के बाद एक पेमेंट कोड का दोगुना होना)। प्रोडक्शन में आने वाले नए कोड्स पर भी नज़र रखें। अगर कोई ऐसा कोड दिखाई दे जो दस्तावेज़ित सूची में नहीं है, तो किसी ने अनुबंध बायपास कर दिया होगा।
जल्दी तय करें कि क्या आंतरिक रहेगा और क्या क्लाइंट्स को जाएगा। एक व्यावहारिक विभाजन यह है: क्लाइंट्स को एक स्थिर कोड, एक लोकलाइज़ेशन की, और एक यूज़र-एक्शन hint मिलता है; लॉग्स में कच्चा exception, स्टैक ट्रेस, रिक्वेस्ट ID, और डिपेंडेंसी फेल्यर्स (डाटाबेस, पेमेंट प्रोवाइडर, ईमेल गेटवे) रहें।
महीने में एक बार, रियल सपोर्ट बातचीतों का उपयोग करके त्रुटियों की समीक्षा करें। आकार के हिसाब से शीर्ष पाँच कोड्स चुनें और हर एक के लिए कुछ टिकट/चैट लॉग पढ़ें। अगर उपयोगकर्ता बार-बार वही follow-up सवाल पूछ रहे हैं, तो UI hint में कोई कदम छूट रहा है या संदेश बहुत अस्पष्ट है।
अगले कदम: अपने प्रोडक्ट और वर्कफ़्लो में पैटर्न लागू करें
जहाँ भ्रम सबसे महंगा है वहाँ से शुरू करें: वे स्टेप्स जिनमें सबसे अधिक ड्रॉप-ऑफ होता है (अक्सर signup, checkout, या file upload) और वे त्रुटियाँ जो सबसे ज्यादा टिकट बनाती हैं। पहले उन्हें मानकीकृत करें ताकि आप एक स्प्रिंट में प्रभाव देख सकें।
एक व्यावहारिक तरीका rollout को फोकस्ड रखने का:
- टॉप 10 सपोर्ट-ड्राइविंग त्रुटियाँ चुनें और उनके लिए स्थिर कोड और सुरक्षित डिफ़ॉल्ट असाइन करें
- कोड -> UI hint -> अगला कदम मैपिंग प्रत्येक सतह (web, mobile, admin) के लिए परिभाषित करें
- नए एंडपॉइंट्स के लिए अनुबंध को डिफ़ॉल्ट बनाएं और गायब फ़ील्ड्स को रिव्यू फेल के रूप में देखें
- एक छोटी आंतरिक प्लेबुक रखें: हर कोड का मतलब क्या है, सपोर्ट क्या मांगता है, और किसका मालिक कौन है
- कुछ मेट्रिक्स ट्रैक करें: कोड के हिसाब से एरर रेट, "unknown error" की गिनती, और हर कोड से जुड़े टिकट वॉल्यूम
अगर आप AppMaster (appmaster.io) के साथ बना रहे हैं, तो इसे शुरुआती चरण में शामिल करना फायदेमंद है: अपने एंडपॉइंट्स के लिए एक सुसंगत त्रुटि शेप परिभाषित करें, फिर वेब और मोबाइल स्क्रीन में स्थिर कोड्स को UI संदेशों से मैप करें ताकि उपयोगकर्ता हर जगह एक समान अर्थ पाएं।
एक सरल उदाहरण: अगर सपोर्ट को बार-बार "Payment failed" शिकायतें मिल रही हैं, तो मानकीकरण से UI एक कोड के लिए "Card declined" और एक अन्य के लिए "Payment system temporarily unavailable" जैसा स्पष्ट संकेत दिखा सकेगा। सपोर्ट trace_id माँगकर अनुमान लगाने के बजाय सटीक घटना देख सकता है।
नियमित साफ-सफ़ाई को कैलेंडर में रखें। अप्रयुक्त कोड्स को रिटायर करें, अस्पष्ट संदेशों को सख़्त करें, और जहाँ वॉल्यूम अधिक है वहाँ लोकलाइज़ेशन जोड़ें। अनुबंध स्थिर रहे जबकि प्रोडक्ट बदलता रहे।


