एपीआई से जुड़ी गड़बड़ियों को समझना

इस गाइड में, Data Manager API से मिलने वाली गड़बड़ियों को हैंडल करने और उनके बारे में बताने के तरीके के बारे में जानकारी दी गई है. एपीआई से मिलने वाली गड़बड़ियों के स्ट्रक्चर और उनके मतलब को समझना ज़रूरी है. इससे ऐसे मज़बूत ऐप्लिकेशन बनाए जा सकते हैं जो अमान्य इनपुट से लेकर सेवा के अस्थायी तौर पर उपलब्ध न होने तक की समस्याओं को आसानी से हैंडल कर सकें.

Data Manager API, Google API के गड़बड़ी के स्टैंडर्ड मॉडल का इस्तेमाल करता है. यह मॉडल, gRPC स्टेटस कोड पर आधारित है . एपीआई के हर ऐसे जवाब में, जिसमें कोई गड़बड़ी होती है, Status ऑब्जेक्ट शामिल होता है. इस ऑब्जेक्ट में ये चीज़ें शामिल होती हैं:

  • गड़बड़ी का कोई न्यूमेरिक कोड.
  • गड़बड़ी का कोई मैसेज.
  • गड़बड़ी के बारे में ज़्यादा जानकारी. यह जानकारी देना ज़रूरी नहीं है.

कैननिकल गड़बड़ी कोड

Data Manager API, कैननिकल गड़बड़ी कोड के सेट का इस्तेमाल करता है, जो gRPC और एचटीटीपी से तय किए गए हैं. इन कोड से, गड़बड़ी के टाइप के बारे में सामान्य जानकारी मिलती है. समस्या की बुनियादी वजह समझने के लिए, आपको हमेशा सबसे पहले इस कोड की जांच करनी चाहिए.

इन कोड के बारे में ज़्यादा जानकारी के लिए, एपीआई डिज़ाइन गाइड - गड़बड़ी कोड देखें.

फ़ास्ट-फ़ेल मॉडल

Data Manager API, फ़ास्ट-फ़ेल मॉडल का इस्तेमाल करता है. अगर किसी अनुरोध में मौजूद कोई रिकॉर्ड, बुनियादी पुष्टि में पास नहीं होता है, तो पूरा अनुरोध पूरा नहीं होता. साथ ही, एपीआई उस अनुरोध में मौजूद किसी भी डेटा को प्रोसेस नहीं करता.

फ़ास्ट-फ़ेल मॉडल, Google के कुछ अन्य एपीआई में इस्तेमाल होने वाले पार्शियल फ़ेल मॉडल से अलग है. जैसे, Google Ads API और Campaign Manager 360 API. पार्शियल फ़ेल मॉडल में, अगर कुछ रिकॉर्ड में गड़बड़ियां हैं, तब भी अनुरोध पूरा हो जाता है. साथ ही, जवाब में उन रिकॉर्ड के लिए गड़बड़ी की जानकारी शामिल होती है जो पूरे नहीं हो सके.

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

फ़ास्ट-फ़ेल मॉडल, इन समस्याओं से बचाता है. इसके लिए, यह आपको अपने डेटा या इंटिग्रेशन से जुड़ी समस्याओं के बारे में तुरंत अलर्ट करता है, ताकि आप सही कार्रवाई कर सकें.

गड़बड़ियों को हैंडल करना

अनुरोध पूरा न होने पर, यह तरीका अपनाएं:

  1. गड़बड़ी के टाइप का पता लगाने के लिए, गड़बड़ी का कोड देखें.

    • अगर gRPC का इस्तेमाल किया जाता है, तो गड़बड़ी का कोड, code फ़ील्ड में होता है Status. अगर क्लाइंट लाइब्रेरी का इस्तेमाल किया जाता है, तो हो सकता है कि यह गड़बड़ी के कोड के हिसाब से, किसी खास टाइप का अपवाद दिखाए. उदाहरण के लिए, अगर गड़बड़ी का कोड INVALID_ARGUMENT है, तो Java के लिए क्लाइंट लाइब्रेरी, com.google.api.gax.rpc.InvalidArgumentException दिखाता है.
    • अगर REST का इस्तेमाल किया जाता है, तो गड़बड़ी का कोड, गड़बड़ी के जवाब में error.status पर होता है. साथ ही, इससे जुड़ा एचटीटीपी स्टेटस, error.code पर होता है.
  2. गड़बड़ी के कोड के लिए, स्टैंडर्ड जानकारी वाला पेलोड देखें. स्टैंडर्ड जानकारी वाले पेलोड, Google API से मिलने वाली गड़बड़ियों के लिए मैसेज का सेट होते हैं . इनसे आपको गड़बड़ी की जानकारी, स्ट्रक्चर्ड और एक जैसे तरीके से मिलती है. Data Manager API से मिलने वाली हर गड़बड़ी के लिए, स्टैंडर्ड जानकारी वाले पेलोड के कई मैसेज हो सकते हैं. Data Manager API की क्लाइंट लाइब्रेरी में, गड़बड़ी से स्टैंडर्ड जानकारी वाले पेलोड पाने के लिए, हेल्पर तरीके होते हैं.

    हमारा सुझाव है कि गड़बड़ी का कोड चाहे कोई भी हो, ErrorInfo, RequestInfo, Help, और LocalizedMessage पेलोड की जांच करें और उन्हें लॉग करें.

    • ErrorInfo में ऐसी जानकारी होती है जो अन्य पेलोड में नहीं हो सकती.
    • RequestInfo में अनुरोध आईडी होता है. अगर आपको सहायता टीम से संपर्क करना है, तो यह आईडी काम का होता है.
    • Help और LocalizedMessage में, गड़बड़ी को ठीक करने में आपकी मदद करने के लिए लिंक और अन्य जानकारी होती है.

    इसके अलावा, BadRequest पेलोड, INVALID_ARGUMENT गड़बड़ियों के लिए काम का होता है. इसकी वजह यह है कि इससे उन फ़ील्ड के बारे में जानकारी मिलती है जिनकी वजह से गड़बड़ी हुई.

स्टैंडर्ड जानकारी वाले पेलोड

Data Manager API के लिए, स्टैंडर्ड जानकारी वाले सबसे आम पेलोड ये हैं:

BadRequest

जब कोई अनुरोध, INVALID_ARGUMENT (एचटीटीपी स्टेटस कोड 400) के साथ पूरा न हो, तो BadRequest पेलोड देखें.

BadRequest मैसेज से पता चलता है कि अनुरोध में ऐसे फ़ील्ड थे जिनकी वैल्यू सही नहीं थीं या किसी ज़रूरी फ़ील्ड के लिए कोई वैल्यू नहीं थी. यह पता लगाने के लिए कि किन फ़ील्ड में गड़बड़ियां हैं, BadRequest में मौजूद field_violations सूची देखें. field_violations की हर एंट्री में, गड़बड़ी को ठीक करने में आपकी मदद करने के लिए जानकारी होती है:

field

अनुरोध में फ़ील्ड की जगह. इसके लिए, कैमल केस पाथ सिंटैक्स का इस्तेमाल किया जाता है.

अगर कोई पाथ, सूची में मौजूद किसी आइटम (कोई repeated फ़ील्ड) की ओर इशारा करता है, तो उसका इंडेक्स, सूची के नाम के बाद स्क्वेयर ब्रैकेट ([...]) में दिखता है.

उदाहरण के लिए, destinations[0].operating_account.account_id account_id सूची में मौजूद पहले आइटम के operating_account में मौजूद destinations है.

description

इस बारे में जानकारी कि वैल्यू की वजह से गड़बड़ी क्यों हुई.

reason

The ErrorReason enum. जैसे, INVALID_HEX_ENCODING या INVALID_CURRENCY_CODE.

BadRequest के उदाहरण

INVALID_ARGUMENT गड़बड़ी के लिए, BadRequest मैसेज के साथ जवाब का एक सैंपल यहां दिया गया है. field_violations से पता चलता है कि गड़बड़ी, accountId की है जो कोई संख्या नहीं है. field वैल्यू destinations[0].login_account.account_id से पता चलता है कि accountId में गड़बड़ी, login_account में मौजूद पहले आइटम की destinations सूची में है.

{
  "error": {
    "code": 400,
    "message": "There was a problem with the request.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "INVALID_ARGUMENT",
        "domain": "datamanager.googleapis.com",
        "metadata": {
          "requestId": "t-a8896317-069f-4198-afed-182a3872a660"
        }
      },
      {
        "@type": "type.googleapis.com/google.rpc.RequestInfo",
        "requestId": "t-a8896317-069f-4198-afed-182a3872a660"
      },
      {
        "@type": "type.googleapis.com/google.rpc.BadRequest",
        "fieldViolations": [
          {
            "field": "destinations[0].login_account.account_id",
            "description": "String is not a valid number.",
            "reason": "INVALID_NUMBER_FORMAT"
          }
        ]
      }
    ]
  }
}

INVALID_ARGUMENT गड़बड़ी के लिए, BadRequest मैसेज के साथ जवाब का एक और सैंपल यहां दिया गया है. इस मामले में, field_violations सूची में दो गड़बड़ियां दिखती हैं:

  1. पहले event की वैल्यू, इवेंट के दूसरे यूज़र आइडेंटिफ़ायर पर हेक्स-एनकोड नहीं की गई है.

  2. दूसरे event की वैल्यू, इवेंट के तीसरे यूज़र आइडेंटिफ़ायर पर हेक्स-एनकोड नहीं की गई है.

{
  "error": {
    "code": 400,
    "message": "There was a problem with the request.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "INVALID_ARGUMENT",
        "domain": "datamanager.googleapis.com",
        "metadata": {
          "requestId": "t-6bc8fb83-d648-4942-9c49-2604276638d8"
        }
      },
      {
        "@type": "type.googleapis.com/google.rpc.RequestInfo",
        "requestId": "t-6bc8fb83-d648-4942-9c49-2604276638d8"
      },
      {
        "@type": "type.googleapis.com/google.rpc.BadRequest",
        "fieldViolations": [
          {
            "field": "events.events[0].user_data.user_identifiers[1]",
            "description": "The HEX encoded value is malformed.",
            "reason": "INVALID_HEX_ENCODING"
          },
          {
            "field": "events.events[1].user_data.user_identifiers[2]",
            "description": "The HEX encoded value is malformed.",
            "reason": "INVALID_HEX_ENCODING"
          }
        ]
      }
    ]
  }
}

RequestInfo

जब भी कोई अनुरोध पूरा न हो, तो RequestInfo पेलोड देखें. RequestInfo में request_id होता है. यह आईडी, आपके एपीआई अनुरोध की खास तौर पर पहचान करता है.

{
  "@type": "type.googleapis.com/google.rpc.RequestInfo",
  "requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}

गड़बड़ियों को लॉग करते समय या सहायता टीम से संपर्क करते समय, समस्याओं की पहचान करने में मदद पाने के लिए, अनुरोध आईडी शामिल करना न भूलें.

ErrorInfo

ErrorInfo मैसेज देखें, ताकि आपको ऐसी ज़्यादा जानकारी मिल सके जो स्टैंडर्ड जानकारी वाले अन्य पेलोड में कैप्चर नहीं की गई हो. ErrorInfo पेलोड में, गड़बड़ी के बारे में जानकारी के साथ metadata मैप होता है.

उदाहरण के लिए, यहां ErrorInfo दिया गया है. यह PERMISSION_DENIED गड़बड़ी के लिए है. यह गड़बड़ी, Google Cloud प्रोजेक्ट के क्रेडेंशियल का इस्तेमाल करने की वजह से हुई है. इस प्रोजेक्ट में, Data Manager API चालू नहीं है. ErrorInfo में गड़बड़ी के बारे में ज़्यादा जानकारी मिलती है. जैसे:

  • अनुरोध से जुड़ा प्रोजेक्ट, metadata.consumer में.
  • सेवा का नाम, metadata.serviceTitle में.
  • वह यूआरएल जहां सेवा को चालू किया जा सकता है, metadata.activationUrl में.
{
  "error": {
    "code": 403,
    "message": "Data Manager API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "SERVICE_DISABLED",
        "domain": "googleapis.com",
        "metadata": {
          "consumer": "projects/PROJECT_NUMBER",
          "service": "datamanager.googleapis.com",
          "containerInfo": "PROJECT_NUMBER",
          "serviceTitle": "Data Manager API",
          "activationUrl": "https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER"
        }
      },
      ...
    ]
  }
}

Help और LocalizedMessage

Help और LocalizedMessage पेलोड देखें, ताकि आपको दस्तावेज़ों के लिंक और गड़बड़ी के स्थानीय भाषा में मैसेज मिल सकें. इनसे आपको गड़बड़ी को समझने और उसे ठीक करने में मदद मिलती है.

उदाहरण के लिए, यहां Help और LocalizedMessage दिया गया है. यह PERMISSION_DENIED गड़बड़ी के लिए है. यह गड़बड़ी, Google Cloud प्रोजेक्ट के क्रेडेंशियल का इस्तेमाल करने की वजह से हुई है. इस प्रोजेक्ट में, Data Manager API चालू नहीं है. Help पेलोड में, वह यूआरएल दिखता है जहां सेवा को चालू किया जा सकता है. साथ ही, LocalizedMessage में गड़बड़ी की जानकारी होती है.

{
  "error": {
    "code": 403,
    "message": "Data Manager API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.LocalizedMessage",
        "locale": "en-US",
        "message": "Data Manager API has not been used in project PROJECT_NUMBER before or it is disabled. Enable it by visiting https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
      },
      {
        "@type": "type.googleapis.com/google.rpc.Help",
        "links": [
          {
            "description": "Google API Console API activation",
            "url": "https://console.cloud.google.com/apis/api/datamanager.googleapis.com/overview?project=PROJECT_NUMBER"
          }
        ]
      },
      ...
    ]
  }
}

गड़बड़ी की जानकारी ऐक्सेस करना

अगर क्लाइंट लाइब्रेरी में से किसी एक का इस्तेमाल किया जा रहा है, तो स्टैंडर्ड जानकारी वाले पेलोड पाने के लिए, हेल्पर तरीकों का इस्तेमाल करें.

.NET

try {
    // Send API request
}
catch (Grpc.Core.RpcException rpcException)
{
    Console.WriteLine($"Exception encountered: {rpcException.Message}");
    var statusDetails =
        Google.Api.Gax.Grpc.RpcExceptionExtensions.GetAllStatusDetails(
            rpcException
        );
    foreach (var detail in statusDetails)
    {
        if (detail is Google.Rpc.BadRequest)
        {
            Google.Rpc.BadRequest badRequest = (Google.Rpc.BadRequest)detail;
            foreach (
                BadRequest.Types.FieldViolation? fieldViolation in badRequest.FieldViolations
            )
            {
                // Access attributes such as fieldViolation!.Reason and fieldViolation!.Field
            }
        }
        else if (detail is Google.Rpc.RequestInfo)
        {
            Google.Rpc.RequestInfo requestInfo = (Google.Rpc.RequestInfo)detail;
            string requestId = requestInfo.RequestId;
            // Log the requestId...
        }
        else if (detail is Google.Rpc.ErrorInfo)
        {
            Google.Rpc.ErrorInfo errorInfo = (Google.Rpc.ErrorInfo)detail;
            // Log the errorInfo.Reason and errorInfo.Metadata...

            // Log the details in the 'Metadata' map...
            foreach (
                KeyValuePair<String, String> metadataEntry in errorInfo.Metadata
            )
            {
                // Log the metadataEntry.Key and metadataEntry.Value...
            }
        }
        else
        {
            // ...
        }
    }
}

Java

try {
  // Send API request
} catch (com.google.api.gax.rpc.InvalidArgumentException invalidArgumentException) {
  // Gets the standard BadRequest payload from the exception.
  BadRequest badRequest = invalidArgumentException.getErrorDetails().getBadRequest();
  for (int i = 0; i < badRequest.getFieldViolationsCount(); i++) {
    FieldViolation fieldViolation = badRequest.getFieldViolations(i);
    // Access attributes such as fieldViolation.getField() and fieldViolation.getReason()
  }

  // Gets the standard RequestInfo payload from the exception.
  RequestInfo requestInfo = invalidArgumentException.getErrorDetails().getRequestInfo();
  if (requestInfo != null) {
    String requestId = requestInfo.getRequestId();
    // Log the requestId...
  }
} catch (com.google.api.gax.rpc.ApiException apiException) {
  // Fallback exception handler for other types of ApiException.

  // Gets the standard ErrorInfo payload from the exception.
  ErrorInfo errorInfo = apiException.getErrorDetails().getErrorInfo();
  // Log the 'reason' and 'domain'...

  // Log the details in the 'metadata' map...
  for (Entry<String, String> metadataEntry : errorInfo.getMetadataMap().entrySet()) {
    // Log the metadataEntry key and value...
  }

  // Gets the standard RequestInfo payload from the exception.
  RequestInfo requestInfo = invalidArgumentException.getErrorDetails().getRequestInfo();
  if (requestInfo != null) {
    String requestId = requestInfo.getRequestId();
    // Log the requestId...
  }
  ...
}

गड़बड़ी को हैंडल करने के सबसे सही तरीके

मज़बूत ऐप्लिकेशन बनाने के लिए, यहां दिए गए सबसे सही तरीके अपनाएं.

गड़बड़ी की जानकारी की जांच करना
हमेशा स्टैंडर्ड जानकारी वाले किसी पेलोड को देखें. जैसे, BadRequest. स्टैंडर्ड जानकारी वाले हर पेलोड में, गड़बड़ी की वजह समझने में आपकी मदद करने के लिए जानकारी होती है.
क्लाइंट और सर्वर की गड़बड़ियों में अंतर करना

यह पता लगाएं कि गड़बड़ी, आपके लागू करने के तरीके (क्लाइंट) में किसी समस्या की वजह से हुई है या एपीआई (सर्वर) में किसी समस्या की वजह से.

  • क्लाइंट की गड़बड़ियां: कोड, जैसे कि INVALID_ARGUMENT, NOT_FOUND, PERMISSION_DENIED, FAILED_PRECONDITION, UNAUTHENTICATED. इनके लिए, अनुरोध या आपके ऐप्लिकेशन के स्टेटस/क्रेडेंशियल में बदलाव करने की ज़रूरत होती है. समस्या को ठीक किए बिना, अनुरोध को फिर से न करें.
  • सर्वर की गड़बड़ियां: कोड, जैसे कि UNAVAILABLE, INTERNAL, DEADLINE_EXCEEDED, UNKNOWN. इनसे पता चलता है कि एपीआई सेवा में अस्थायी समस्या है.
फिर से कोशिश करने की रणनीति लागू करना

यह पता लगाएं कि गड़बड़ी के लिए फिर से कोशिश की जा सकती है या नहीं. साथ ही, फिर से कोशिश करने की रणनीति का इस्तेमाल करें.

  • सर्वर की अस्थायी गड़बड़ियों के लिए सिर्फ़ फिर से कोशिश करें. जैसे, UNAVAILABLE, DEADLINE_EXCEEDED, INTERNAL, UNKNOWN, और ABORTED.
  • फिर से कोशिश करने के बीच इंतज़ार की अवधि बढ़ाने के लिए, एक्स्पोनेंशियल बैकऑफ़ एल्गोरिदम का इस्तेमाल करें. इससे, पहले से ही लोड वाली सेवा पर ज़्यादा लोड पड़ने से बचा जा सकता है. उदाहरण के लिए, 1 सेकंड, फिर 2 सेकंड, फिर 4 सेकंड इंतज़ार करें. फिर से कोशिश करने की ज़्यादा से ज़्यादा संख्या या कुल इंतज़ार के समय तक, इसी तरह इंतज़ार करें.
  • बैकऑफ़ में लगने वाले समय में, "जिटर" की थोड़ी सी रैंडम वैल्यू जोड़ें, ताकि "थंडरिंग हर्ड" की समस्या से बचा जा सके. इस समस्या में, कई क्लाइंट एक साथ फिर से कोशिश करते हैं.
पूरी जानकारी लॉग करना

गड़बड़ी का पूरा जवाब लॉग करें. इसमें स्टैंडर्ड जानकारी वाले सभी पेलोड शामिल होने चाहिए. खास तौर पर, अनुरोध आईडी. अगर ज़रूरत हो, तो डीबग करने और Google की सहायता टीम को समस्याओं की रिपोर्ट करने के लिए, यह जानकारी ज़रूरी है.

उपयोगकर्ता से सुझाव, शिकायत या राय पाना

स्टैंडर्ड जानकारी वाले पेलोड में मौजूद कोड और मैसेज के आधार पर, अपने ऐप्लिकेशन के उपयोगकर्ताओं को साफ़ और काम के सुझाव, शिकायत या राय दें. उदाहरण के लिए, सिर्फ़ "कोई गड़बड़ी हुई" कहने के बजाय, "ट्रांज़ैक्शन आईडी मौजूद नहीं था" या "मंज़िल का खाता आईडी नहीं मिला" कहा जा सकता है.

इन दिशा-निर्देशों का पालन करके, Data Manager API से मिलने वाली गड़बड़ियों की पहचान और उन्हें ठीक किया जा सकता है. इससे ज़्यादा स्थिर और उपयोगकर्ता के लिए आसान ऐप्लिकेशन बनाए जा सकते हैं.