آشنایی با خطاهای میانای برنامه‌سازی کاربردی

این راهنما توضیح می‌دهد که Data Manager API چگونه خطاها را مدیریت و اعلام می‌کند. درک ساختار و معنای خطاهای API برای ساختن برنامه‌های قدرتمندی که بتوانند به‌خوبی مشکلات را مدیریت کنند، از ورودی نامعتبر گرفته تا عدم دسترسی موقت به سرویس، بسیار مهم است.

Data Manager API از مدل خطای استاندارد Google API پیروی می‌کند که براساس کدهای وضعیت gRPC است. هر پاسخ میانای برنامه‌سازی کاربردی که منجر به خطا می‌شود شامل یک شیء Status با موارد زیر است:

  • کد خطای عددی.
  • پیام خطا.
  • اختیاری، جزئیات تکمیلی خطا.

کدهای خطای متعارف

Data Manager API از مجموعه‌ای از کدهای خطای متعارف استفاده می‌کند که توسط gRPC و HTTP تعریف شده‌اند. این کدها نشانگر سطح بالایی از نوع خطا ارائه می‌دهند. همیشه باید ابتدا این کد را بررسی کنید تا ماهیت اصلی مشکل را درک کنید.

برای جزئیات بیشتر درباره این کدها، به راهنمای طراحی میانای برنامه‌سازی کاربردی - کدهای خطا مراجعه کنید.

مدل شکست سریع

Data Manager API از مدل شکست سریع استفاده می‌کند. اگر درخواستی حاوی خطاهای ساختاری باشد یا اگر هرکدام از سوابق در اعتبارسنجی فیلد الزامی ناموفق باشد، کل درخواست ناموفق خواهد بود و API هیچ‌کدام از داده‌های آن درخواست را پردازش نمی‌کند.

مقایسه با مدل خرابی جزئی

مدل شکست سریع با مدل شکست جزئی در برخی‌از میاناهای برنامه‌سازی کاربردی دیگر Google، مانند Google Ads API و Campaign Manager 360 API متفاوت است. در مدل شکست جزئی، درخواست موفق می‌شود حتی اگر برخی‌از سوابق خطا داشته باشند، و پاسخ حاوی جزئیات خطا برای سوابق ناموفق است.

اگرچه خرابی جزئی می‌تواند راحت باشد، اما خطرات قابل‌توجهی دارد زیرا مدل خرابی جزئی پیش‌کنشی به شما درباره خطاها هشدار نمی‌دهد—شما باید به‌طور صریح خطاها را در هر پاسخ بررسی کنید. این امر می‌تواند مشکلات مهم را پنهان کند زیرا درخواست موفق می‌شود حتی اگر میانای برنامه‌سازی کاربردی بسیاری از سوابق یا حتی همه سوابق موجود در درخواست را رد کند. اگر بخش قابل‌توجهی از سوابق در یک درخواست دارای خطا باشد اما شما پاسخ را بررسی نکنید، ممکن است کاملاً از مشکلات گسترده در داده‌های خود بی‌خبر بمانید و تنها چند روز یا چند هفته بعد، زمانی که نتایج تجمعی با انتظارات شما همخوانی نداشته باشد، متوجه این مشکلات شوید.

مدل شکست سریع با هشدار دادن فوری به شما درباره مشکلات مربوط به داده‌ها یا ادغام، از این مشکلات جلوگیری می‌کند تا بتوانید اقدام مناسب را انجام دهید.

بررسی خطاهای «شکست سریع» با validateOnly

بیشتر درخواست‌های دریافت و برداشتن محتوا از فیلد validateOnly پشتیبانی می‌کنند. وقتی validateOnly را روی true تنظیم می‌کنید، Data Manager API همان بررسی‌های اعتبارسنجی پایه را که برای درخواست معمولی انجام می‌دهد اجرا می‌کند، اما هیچ داده‌ای را دریافت یا حذف نمی‌کند.

  • اگر درخواست خطا داشته باشد، با همان پاسخ خطایی که از درخواست معمولی دریافت می‌کنید ناموفق می‌شود.
  • اگر درخواست از اعتبارسنجی عبور کند، موفقیت‌آمیز خواهد بود. پاسخ شامل هرگونه fieldWarnings برای فیلدهای اختیاری است، درست مانند یک درخواست معمولی.

از validateOnly برای این کارها استفاده کنید:

  • ادغام جدید یا به‌روزشده را بدون تأثیر بر داده‌های زنده خود آزمایش کنید.
  • پیش‌از ارسال مجدد درخواست، مطمئن شوید که اصلاحیه خطا را برطرف می‌کند.

مدیریت کردن خطاها

وقتی درخواستی ناموفق است، این مراحل را دنبال کنید:

  1. کد خطا را بررسی کنید تا نوع خطا را پیدا کنید.

    • اگر از gRPC استفاده می‌کنید، کد خطا در فیلد code از Status قرار دارد. اگر از کتابخانه کارخواه استفاده می‌کنید، ممکن است نوع خاصی از استثنا را که با کد خطا مطابقت دارد، ایجاد کند. برای مثال، کتابخانه کارخواه برای Java com.google.api.gax.rpc.InvalidArgumentException را درصورت وجود کد خطای INVALID_ARGUMENT برمی‌گرداند.
    • اگر از REST استفاده می‌کنید، کد خطا در پاسخ خطا در error.status است، و وضعیت HTTP مربوطه در error.code است.
  2. بارداده جزئیات استاندارد را برای کد خطا بررسی کنید. محموله‌های جزئیات استاندارد مجموعه‌ای از پیام‌ها برای خطاهای میاناهای برنامه‌سازی کاربردی Google هستند. این کدها جزئیات خطا را به‌صورت ساختاریافته و منسجم به شما ارائه می‌دهند. هر خطا از Data Manager API ممکن است چند پیام محموله جزئیات استاندارد داشته باشد. کتابخانه‌های کارخواه Data Manager API روش‌های کمکی دارند تا محموله جزئیات استاندارد را از خطا دریافت کنند.

    صرف‌نظر از کد خطا، توصیه می‌کنیم بارداده‌های ErrorInfo،‏ RequestInfo،‏ Help، و LocalizedMessage را بررسی و ثبت کنید.

    • ErrorInfo حاوی اطلاعاتی است که ممکن است در محموله‌های دیگر نباشد.
    • RequestInfo شناسه درخواست را دارد که اگر لازم باشد با پشتیبانی تماس بگیرید، مفید است.
    • Help و LocalizedMessage حاوی پیوندها و جزئیات دیگری هستند که به شما کمک می‌کنند خطا را برطرف کنید.

    علاوه‌براین، بار داده BadRequest برای خطاهای INVALID_ARGUMENT مفید است زیرا اطلاعاتی درباره اینکه کدام فیلدها باعث خطا شده‌اند ارائه می‌دهد.

هشدارهای بلعیدن

Data Manager API تا حد امکان درخواست‌های جذب را می‌پذیرد. اگر داده‌هایی را اضافه کنید که الزامی نیستند، عدم درستی‌سنجی آن فیلدها باعث ناموفق شدن درخواست نمی‌شود. برای مثال، اگر شناسه محصول فروشنده برای یکی از موارد سبد خرید وجود نداشته باشد، میانای برنامه‌سازی کاربردی بقیه درخواست را پردازش می‌کند و هشداری برمی‌گرداند.

پاسخ موفقیت‌آمیز دریافت (رمز وضعیت HTTP 200) شامل این هشدارها در فهرست fieldWarnings است. هر ورودی یک شیء FieldWarning با فیلدهای زیر است:

field

مکان فیلد در درخواست، در نحو مسیر نگارش ماری.

اگر مسیری به موردی در فهرست (فیلد repeated) اشاره کند، نمایه آن در کروشه ([...]) بعداز نام فهرست نشان داده می‌شود.

برای مثال، events.events[0].cart_data.items[0].merchant_product_id هشداری را شناسایی می‌کند که مربوط به اولین مورد در داده‌های سبد خرید اولین رویداد در درخواست است.

description

توضیحی درباره اینکه چرا مقدار ارائه‌شده باعث هشدار شده است.

reason

مقدار شمارشی WarningReason که نوع هشدار را مشخص می‌کند.

مثال با FieldWarning

در اینجا نمونه پاسخی برای درخواست موفقیت‌آمیز دریافت داده‌ها آورده شده است که حاوی هشدار است زیرا شناسه محصول فروشنده برای یکی از موارد سبد خرید وجود ندارد.

{
  "requestId": "126365e1-16d0-4c81-9de9-f362711e250a",
  "fieldWarnings": [
    {
      "field": "events.events[0].cart_data.items[0].merchant_product_id",
      "description": "The merchant product ID is missing in the cart item.",
      "reason": "WARNING_REASON_CART_DATA_ITEM_MERCHANT_PRODUCT_ID_MISSING"
    }
  ]
}

بار داده‌های جزئیات استاندارد

رایج‌ترین محموله‌های جزئیات استاندارد برای Data Manager API عبارت‌اند از:

BadRequest

وقتی درخواستی با INVALID_ARGUMENT (رمز وضعیت HTTP 400) ناموفق می‌شود، بار داده BadRequest را بررسی کنید.

پیام BadRequest نشان می‌دهد که درخواست دارای فیلدهایی با مقادیر نادرست بوده است، یا مقدار فیلد الزامی را نداشته است. فهرست field_violations را در BadRequest بررسی کنید تا ببینید کدام فیلدها خطا دارند. هر ورودی field_violations اطلاعاتی دارد که به شما کمک می‌کند خطا را برطرف کنید:

field

مکان فیلد در درخواست، در نحو مسیر نگارش ماری.

اگر مسیری به موردی در فهرست (فیلد repeated) اشاره کند، نمایه آن در کروشه ([...]) بعداز نام فهرست نشان داده می‌شود.

برای مثال، destinations[0].operating_account.account_id account_id در operating_account اولین مورد در فهرست destinations است.

description

توضیحی درباره اینکه چرا این مقدار باعث بروز خطا شده است.

reason

ErrorReason enum، مانند INVALID_HEX_ENCODING یا INVALID_CURRENCY_CODE.

نمونه‌های BadRequest

در اینجا نمونه پاسخی برای خطای INVALID_ARGUMENT با پیام BadRequest آورده شده است. field_violations نشان می‌دهد که خطا یک accountId است که عدد نیست. مقدار fielddestinations[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"
        }
      },
      ...
    ]
  }
}

خطاهای حد نرخ و سهمیه

وقتی درخواستی از حد پروژه فراتر برود، API خطای RESOURCE_EXHAUSTED (کد وضعیت HTTP 429) را برمی‌گرداند. بار خالص ErrorInfo جزئیاتی درباره حدی که از آن فراتر رفته است در نقشه metadata خود ارائه می‌دهد:

consumer
پروژه Google Cloud مرتبط با درخواست، قالب‌بندی‌شده به‌صورت projects/PROJECT_NUMBER.
quota_limit
نام حد سهمیه‌ای که از آن فراتر رفته است، مانند IngestionMutateRequestsPerMinutePerProject یا IngestionMutateRequestsPerDayPerProject. می‌توانید از این مقدار برای تعیین اینکه آیا برنامه از حد مجاز دقیقه‌ای یا حد مجاز روزانه فراتر رفته است یا نه استفاده کنید. برای فهرست کامل نام‌های محدودیت، محدودیت‌های پروژه را ببینید.
quota_location
مکانی که سهمیه در آن اعمال می‌شود. برای Data Manager API، این مقدار همیشه global است.
quota_metric
سنجه مرتبط با محدودیت، مثل datamanager.googleapis.com/ingestion_mutate_requests.
service
نام سرویس، datamanager.googleapis.com.

در اینجا نمونه‌ای از پاسخ خطای RESOURCE_EXHAUSTED آورده شده است که وقتی درخواست از حد مجاز در دقیقه برای درخواست‌های تغییر جذب فراتر می‌رود:

{
  "error": {
    "code": 429,
    "message": "Quota exceeded for quota metric 'Ingestion mutate requests' and limit 'Ingestion mutate requests per minute' of service 'datamanager.googleapis.com' for consumer 'project_number:PROJECT_NUMBER'.",
    "status": "RESOURCE_EXHAUSTED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "RATE_LIMIT_EXCEEDED",
        "domain": "googleapis.com",
        "metadata": {
          "consumer": "projects/PROJECT_NUMBER",
          "quota_limit": "IngestionMutateRequestsPerMinutePerProject",
          "quota_location": "global",
          "quota_metric": "datamanager.googleapis.com/ingestion_mutate_requests",
          "service": "datamanager.googleapis.com"
        }
      }
    ]
  }
}

‫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"
          }
        ]
      },
      ...
    ]
  }
}

دسترسی به جزئیات خطا

اگر از یکی از کتابخانه‌های کارخواه استفاده می‌کنید، از روش‌های کمکی برای دریافت محموله‌های جزئیات استاندارد استفاده کنید.

دات نت

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...

            // If handling a rate limit error, check the exceeded quota limit:
            if (errorInfo.Reason == "RATE_LIMIT_EXCEEDED" &&
                errorInfo.Metadata.TryGetValue("quota_limit", out string quotaLimit))
            {
                // Inspect quotaLimit to determine whether it is a per-minute
                // or daily limit (for example,
                // IngestionMutateRequestsPerMinutePerProject).
            }

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

جاوا

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'...

  // If handling a rate limit error, check the exceeded quota limit:
  if (errorInfo != null && "RATE_LIMIT_EXCEEDED".equals(errorInfo.getReason())) {
    String quotaLimit = errorInfo.getMetadataMap().get("quota_limit");
    // Inspect quotaLimit to determine whether it is a per-minute
    // or daily limit (for example,
    // IngestionMutateRequestsPerMinutePerProject).
  }

  // 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 = apiException.getErrorDetails().getRequestInfo();
  if (requestInfo != null) {
    String requestId = requestInfo.getRequestId();
    // Log the requestId...
  }
  ...
}

رسیدگی به خطاهای اندازه سرصفحه برای gRPC

وقتی تعداد زیادی از سوابق در درخواست استخراج یا برداشتن محتوا اعتبارسنجی نشوند، Data Manager API همه خطاها را در محموله BadRequest پاسخ برمی‌گرداند.

در gRPC، سرویس این جزئیات خطا را در سرایندهای پاسخ HTTP/2 (فراداده) برمی‌گرداند. به‌طور پیش‌فرض، کتابخانه‌های مشتری gRPC سرصفحه‌های ورودی را به حداکثر اندازه (معمولاً ۸ تا ۱۰ کیلوبایت) محدود می‌کنند. اگر جزئیات خطا از این حد فراتر رود، انتقال HTTP/2 سمت کارخواه قبل‌از تجزیه پاسخ خطا ناموفق می‌شود و استثنایی مانند زیر ایجاد می‌کند:

Http2Exception: Header size exceeded max allowed size (10240)

چون کارخواه نمی‌تواند سرایندهای پاسخ را پردازش کند، جاری‌سازی را لغو می‌کند (که به‌صورت وضعیت HTTP 499 Client Closed Request در گزارش‌های سمت سرور نشان داده می‌شود)، و برنامه شما نمی‌تواند به جزئیات خطای BadRequest دسترسی پیدا کند.

برای حل این مشکل و بررسی فهرست کامل خطاها، سرویس‌گیرنده gRPC خود را با حداکثر اندازه فراداده ورودی افزایش‌یافته (مانند ۱۶ مگابایت) پیکربندی کنید:

دات نت

// Creates a client for the ingestion service. Increases the maximum metadata size to
// 16MB to prevent RESOURCE_EXHAUSTED errors when responses contain large error
// details.
IngestionServiceClient ingestionServiceClient = new IngestionServiceClientBuilder
{
    GrpcChannelOptions = GrpcChannelOptions.Empty.WithCustomOption(
        "grpc.max_metadata_size",
        16 * 1024 * 1024
    ),
}.Build();

جاوا

// Creates a client for the ingestion service. Increases the maximum metadata size to 16MB to
// prevent RESOURCE_EXHAUSTED errors when responses contain large error details.
InstantiatingGrpcChannelProvider provider =
    IngestionServiceSettings.defaultGrpcTransportProviderBuilder()
        .setMaxInboundMetadataSize(16 * 1024 * 1024)
        .build();
IngestionServiceSettings settings =
    IngestionServiceSettings.newBuilder().setTransportChannelProvider(provider).build();
try (IngestionServiceClient ingestionServiceClient = IngestionServiceClient.create(settings)) {
  // ...
}

Node

// Creates a client for the ingestion service. Increases the maximum metadata
// size to 16MB to prevent RESOURCE_EXHAUSTED errors when responses contain
// large error details.
const client = new IngestionServiceClient({
  'grpc.max_metadata_size': 16 * 1024 * 1024,
});

PHP

// Creates a client for the ingestion service. Increases the maximum metadata size to 16MB to
// prevent RESOURCE_EXHAUSTED errors when responses contain large error details.
$client = new IngestionServiceClient([
    'transportConfig' => [
        'grpc' => [
            'stubOpts' => [
                'grpc.max_metadata_size' => 16 * 1024 * 1024,
            ],
        ],
    ],
]);

Python

# Creates a client for the ingestion service. Increases the maximum
# metadata size to 16MB to prevent RESOURCE_EXHAUSTED errors when responses
# contain large error details.
channel = datamanager_v1.services.ingestion_service.transports.IngestionServiceGrpcTransport.create_channel(
    options=[("grpc.max_metadata_size", 16 * 1024 * 1024)]
)
transport = datamanager_v1.services.ingestion_service.transports.IngestionServiceGrpcTransport(
    channel=channel
)
client: datamanager_v1.IngestionServiceClient = (
    datamanager_v1.IngestionServiceClient(transport=transport)
)

روال‌های مطلوب برای رسیدگی به خطا

برای ساختن برنامه‌های انعطاف‌پذیر، روال‌های مطلوب زیر را پیاده‌سازی کنید.

پیش‌از ارسال، اعتبار سنجی کنید
وقتی ادغامی را می‌سازید یا تغییر می‌دهید، درخواست‌ها را با validateOnly تنظیم‌شده روی true ارسال کنید تا خطاهای سریع-ناموفق را قبل‌از دریافت داده‌ها بگیرید.
بررسی جزئیات خطا
همیشه به‌دنبال یکی از محموله‌های جزئیات استاندارد مثل BadRequest باشید. هر بار داده جزئیات استاندارد حاوی اطلاعاتی است که به شما کمک می‌کند علت خطا را درک کنید.
تمیز خطاهای کارخواه از خطاهای سرور

تعیین کنید که آیا خطا ناشی از مشکلی در پیاده‌سازی شما (سمت کارخواه) است یا مشکلی در میانای برنامه‌سازی کاربردی (سمت سرور).

  • خطاهای کارخواه: کدهایی مثل INVALID_ARGUMENT، NOT_FOUND، PERMISSION_DENIED، FAILED_PRECONDITION، UNAUTHENTICATED. این موارد نیاز به تغییر در درخواست یا وضعیت/اعتبارنامه برنامه‌تان دارد. بدون رسیدگی به مشکل، درخواست را دوباره امتحان نکنید.
  • خطاهای سرور: کدهایی مثل UNAVAILABLE، INTERNAL، DEADLINE_EXCEEDED، UNKNOWN. این خطاها نشان‌دهنده مشکلی موقت در سرویس API است.
پیاده‌سازی استراتژی تلاش مجدد

تعیین کنید که آیا خطا قابل‌تکرار است یا نه، و از استراتژی تکرار استفاده کنید.

  • فقط برای خطاهای گذرا در سرور (مانند UNAVAILABLE، DEADLINE_EXCEEDED، INTERNAL، UNKNOWN، و ABORTED) و محدودیت‌های نرخ در دقیقه (RESOURCE_EXHAUSTED با RATE_LIMIT_EXCEEDED) دوباره امتحان کنید.

  • برای حد نرخ، quota_limit را در ErrorInfo بررسی کنید:

    • اگر محدودیت در دقیقه است (مثل IngestionMutateRequestsPerMinutePerProject)، درخواست‌ها را موقتاً متوقف کنید و بااستفاده از عقب‌نشینی نمایی با لرزش دوباره امتحان کنید.

    • اگر حد روزانه است (مثل IngestionMutateRequestsPerDayPerProject)، فوراً دوباره امتحان نکنید. پردازش را تا زمان بازنشانی سهمیه روزانه در نیمه‌شب به‌وقت اقیانوس آرام موقتاً متوقف کنید.

  • از الگوریتم عقب‌گرد نمایی برای افزایش دوره‌های انتظار بین تلاش‌های مجدد استفاده کنید. این کار کمک می‌کند تا از تحت فشار قرار گرفتن سرویسی که ازقبل تحت فشار است جلوگیری شود. برای مثال، ۱ ثانیه، سپس ۲ ثانیه، سپس ۴ ثانیه صبر کنید و این کار را تا رسیدن به حداکثر تعداد تلاش‌های مجدد یا کل زمان انتظار ادامه دهید.

  • مقدار تصادفی کوچکی از «لرزش» را به تأخیرهای عقب‌نشینی اضافه کنید تا از مشکل «گله رعدآسا» که در آن بسیاری از مشتریان به‌طور هم‌زمان دوباره امتحان می‌کنند، جلوگیری شود.

ثبت کامل گزارش

پاسخ کامل خطا را ثبت کنید، ازجمله همه محموله‌های جزئیات استاندارد، به‌ویژه شناسه درخواست. این اطلاعات برای اشکال‌زدایی و گزارش کردن مشکلات به پشتیبانی Google (درصورت نیاز) ضروری است.

ارائه بازخورد کاربر

براساس کدها و پیام‌های موجود در محموله‌های جزئیات استاندارد، بازخورد واضح و مفیدی به کاربران برنامه‌تان ارائه دهید. برای مثال، به‌جای اینکه فقط بگویید «خطایی روی داد»، می‌توانید بگویید «شناسه تراکنش وجود نداشت» یا «شناسه حساب مقصد پیدا نشد».

با دنبال کردن این دستورالعمل‌ها، می‌توانید به‌طور مؤثر خطاهای برگردانده‌شده توسط Data Manager API را تشخیص دهید و مدیریت کنید، که منجر به برنامه‌های پایدارتر و کاربرپسندتر می‌شود.