במדריך הזה מוסבר איך המערכת של Data Manager API מטפלת בשגיאות ומדווחת עליהן. כדי לפתח אפליקציות חזקות שיכולות להתמודד בצורה חלקה עם בעיות, החל מקלט לא חוקי ועד לחוסר זמינות זמנית של השירות, חשוב להבין את המבנה והמשמעות של שגיאות API.
Data Manager API פועל לפי מודל השגיאות הרגיל של Google API, שמבוסס על קודי הסטטוס של gRPC. כל תגובה מה-API שגורמת לשגיאה כוללת אובייקט Status עם:
- קוד שגיאה מספרי.
- הודעת שגיאה.
- אופציונלי, פרטים נוספים על השגיאה.
קודי שגיאה קנוניים
Data Manager API משתמש בקבוצה של קודי שגיאה קנוניים שמוגדרים על ידי gRPC ו-HTTP. הקודים האלה מספקים אינדיקציה כללית לגבי סוג השגיאה. תמיד כדאי לבדוק קודם את הקוד הזה כדי להבין את מהות הבעיה.
לפרטים נוספים על הקודים האלה, ראו מדריך לעיצוב API – קודי שגיאה.
מודל של כישלון מהיר
Data Manager API משתמש במודל של כשל מהיר. אם בקשה מכילה שגיאות מבניות או אם רשומה כלשהי נכשלת באימות של שדה חובה, הבקשה כולה נכשלת וה-API לא מעבד את הנתונים בבקשה הזו.
השוואה למודל הכישלון החלקי
מודל הכישלון המהיר שונה ממודל הכישלון החלקי בממשקי API אחרים של Google, כמו Google Ads API ו-Campaign Manager 360 API. במודל של כישלון חלקי, הבקשה מצליחה גם אם בחלק מהרשומות יש שגיאות, והתשובה מכילה פרטי שגיאה לגבי הרשומות שנכשלו.
למרות שכישלון חלקי יכול להיות נוח, הוא כרוך בסיכונים משמעותיים כי מודל הכישלון החלקי לא מתריע באופן יזום על שגיאות – צריך לבדוק באופן מפורש אם יש שגיאות בכל תשובה. זה יכול להסתיר בעיות חשובות, כי הבקשה מצליחה גם אם ה-API דוחה הרבה מהרשומות בבקשה, או אפילו את כולן. אם בחלק משמעותי מהרשומות בבקשה יש שגיאות, אבל אתם לא בודקים את התגובה, יכול להיות שלא תהיו מודעים בכלל לבעיות נרחבות בנתונים שלכם, ותגלו את הבעיות האלה רק כמה ימים או שבועות לאחר מכן, כשהתוצאות המצטברות לא יתאימו לציפיות שלכם.
מודל הכשל המהיר מונע את הבעיות האלה על ידי התראה מיידית על בעיות בנתונים או בשילוב, כדי שתוכלו לנקוט את הפעולה המתאימה.
בדיקה אם יש שגיאות מסוג fast-fail באמצעות validateOnly
רוב הבקשות להטמעת נתונים ובקשות להסרת תוכן תומכות בשדה validateOnly. כשמגדירים את validateOnly לערך true, ה-Data Manager API מריץ את אותן בדיקות אימות בסיסיות כמו בבקשה רגילה, אבל לא מטמיע או מסיר נתונים.
- אם יש שגיאות בבקשה, היא תיכשל עם אותה תגובת שגיאה שהייתם מקבלים מבקשה רגילה.
- אם הבקשה עוברת את האימות, היא מצליחה. התשובה כוללת את כל השגיאות מסוג
fieldWarningsבשדות אופציונליים, בדיוק כמו בבקשה רגילה.
אפשר להשתמש בvalidateOnly כדי:
- לבדוק שילוב חדש או מעודכן בלי להשפיע על הנתונים בזמן אמת.
- לפני ששולחים מחדש את הבקשה, צריך לוודא שהתיקון פותר את השגיאה.
טיפול בשגיאות
אם הבקשה נכשלת, פועלים לפי השלבים הבאים:
בודקים את קוד השגיאה כדי לזהות את סוג השגיאה.
- אם אתם משתמשים ב-gRPC, קוד השגיאה מופיע בשדה
codeשלStatus. אם אתם משתמשים בספריית לקוח, יכול להיות שהיא תציג סוג ספציפי של חריגה שתואם לקוד השגיאה. לדוגמה, ספריית הלקוח של Java מחזירהcom.google.api.gax.rpc.InvalidArgumentExceptionאם קוד השגיאה הואINVALID_ARGUMENT. - אם אתם משתמשים ב-REST, קוד השגיאה נמצא בתגובת השגיאה ב-
error.status, וסטטוס ה-HTTP התואם נמצא ב-error.code.
- אם אתם משתמשים ב-gRPC, קוד השגיאה מופיע בשדה
בודקים את מטען הייעודי (payload) של הפרטים הסטנדרטיים של קוד השגיאה. מטעני הייעודיים הסטנדרטיים של הפרטים הם קבוצת הודעות לשגיאות מ-Google APIs. הם מספקים פרטים על השגיאה בצורה מובנית ועקבית. כל שגיאה מ-Data Manager API יכולה לכלול כמה הודעות מטען ייעודי (payload) עם פרטים סטנדרטיים. בספריות הלקוח של Data Manager API יש שיטות עזר לקבלת המטענים הייעודיים (payloads) הסטנדרטיים של פרטי השגיאה.
לא משנה מה קוד השגיאה, מומלץ לבדוק את המטענים הייעודיים (payloads) של
ErrorInfo,RequestInfo,Helpו-LocalizedMessageולתעד אותם ביומן.- השדה
ErrorInfoמכיל מידע שאולי לא מופיע במטענים ייעודיים אחרים. -
RequestInfoמכיל את מזהה הבקשה, שיכול לעזור אם צריך לפנות לתמיכה. - השגיאות
Helpו-LocalizedMessageמכילות קישורים ופרטים נוספים שיעזרו לכם לטפל בשגיאה.
בנוסף, המטען הייעודי (payload) של
BadRequestשימושי לשגיאותINVALID_ARGUMENTכי הוא מספק מידע על השדות שגרמו לשגיאה.- השדה
אזהרות לגבי הטמעה
Data Manager API מקבל כמה שיותר נתונים מבקשת ההטמעה. אם תכללו נתונים לא נדרשים, כשלים באימות של השדות האלה לא יגרמו לבקשה להיכשל. לדוגמה, אם חסר מזהה מוצר של מוכר בפריט בעגלת הקניות, ה-API מעבד את שאר הבקשה ומחזיר אזהרה.
תגובת הטמעה מוצלחת (קוד סטטוס של HTTP 200) כוללת את האזהרות האלה ברשימת fieldWarnings. כל רשומה היא אובייקט FieldWarning עם השדות הבאים:
fieldהמיקום של השדה בבקשה, בתחביר נתיב של קו תחתון בין המילים.
אם נתיב מצביע לפריט ברשימה (שדה
repeated), האינדקס שלו מוצג בסוגריים מרובעים ([...]) אחרי שם הרשימה.לדוגמה,
events.events[0].cart_data.items[0].merchant_product_idמזהה אזהרה שקשורה לפריט הראשון בנתוני עגלת הקניות של האירוע הראשון בבקשה.descriptionהסבר למה הערך שצוין גרם לאזהרה.
reasonערך ה-enum של
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"
}
]
}
מטענים ייעודיים (payloads) סטנדרטיים של פרטים
אלה המטענים הייעודיים (payloads) הנפוצים ביותר של פרטים סטנדרטיים ב-Data Manager API:
BadRequest
בודקים את המטען הייעודי (payload) של BadRequest כשבקשה נכשלת עם השגיאה INVALID_ARGUMENT (קוד סטטוס של HTTP 400).
ההודעה BadRequest מציינת שבבקשה היו שדות עם ערכים שגויים, או שהיה חסר ערך בשדה חובה. כדי לראות באילו שדות יש שגיאות, בודקים את הרשימה field_violations בBadRequest. כל רשומה של field_violations כוללת מידע שיעזור לכם לתקן את השגיאה:
fieldהמיקום של השדה בבקשה, בתחביר של נתיב עם קו תחתון בין המילים.
אם נתיב מצביע לפריט ברשימה (שדה
repeated), האינדקס שלו מוצג בסוגריים מרובעים ([...]) אחרי שם הרשימה.לדוגמה,
destinations[0].operating_account.account_idהואaccount_idב-operating_accountשל הפריט הראשון ברשימהdestinations.descriptionהסבר למה הערך גרם לשגיאה.
reasonהערך של
ErrorReason, למשל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 מוצגות שתי שגיאות:
הערך של
eventהראשון לא מקודד בפורמט הקסדצימלי במזהה המשתמש השני של האירוע.השדה השני
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
בכל פעם שבקשה נכשלת, בודקים את המטען הייעודי (payload) של RequestInfo. RequestInfo
מכיל את request_id שמזהה באופן ייחודי את בקשת ה-API שלכם.
{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "t-4490c640-dc5d-4c28-91c1-04a1cae0f49f"
}
כשמתעדים שגיאות או פונים לתמיכה, חשוב לכלול את מזהה הבקשה כדי לעזור באבחון הבעיות.
ErrorInfo
חפשו את ההודעה ErrorInfo כדי לאחזר מידע נוסף שאולי לא נלכד במטענים הייעודיים (payloads) האחרים של הפרטים הרגילים. המטען הייעודי (payload) של ErrorInfo מכיל מפה של metadata עם מידע על השגיאה.
לדוגמה, הנה ErrorInfo של כשל ב-PERMISSION_DENIED שנגרם כתוצאה משימוש בפרטי כניסה לפרויקט בענן של Google Cloud שבו Data Manager API לא מופעל. השדה ErrorInfo מספק מידע נוסף על השגיאה, כמו:
- הפרויקט שמשויך לבקשה, בקטע
metadata.consumer. - שם השירות, בקטע
metadata.serviceTitle. - כתובת ה-URL שבה אפשר להפעיל את השירות, בקטע
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). המטען הייעודי (payload) של ErrorInfo מספק פרטים על המגבלה שנחרגה במפה metadata:
consumer
- הפרויקט בענן של Google שמשויך לבקשה, בפורמט
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
כדי לקבל קישורים למסמכי תיעוד ולהודעות שגיאה מקומיות שיעזרו לכם להבין את השגיאה ולתקן אותה, חפשו את המטענים הייעודיים (payloads) Help ו-LocalizedMessage.
לדוגמה, הנה Help ו-LocalizedMessage של כשל ב-PERMISSION_DENIED שנגרם כתוצאה משימוש בפרטי כניסה לפרויקט בענן ב-Google Cloud שבו Data Manager API לא מופעל. המטען הייעודי (payload) של Help מציג את כתובת ה-URL שבה אפשר להפעיל את השירות, וב-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"
}
]
},
...
]
}
}
פרטי שגיאת הגישה
אם אתם משתמשים באחת מספריות הלקוח, השתמשו בשיטות העזר כדי לקבל את המטענים הייעודיים (payloads) הסטנדרטיים של הפרטים.
.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...
// 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
{
// ...
}
}
}
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'...
// 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 מחזיר את כל השגיאות במטען הייעודי (payload) של BadRequest בתגובה.
ב-gRPC, השירות מחזיר את פרטי השגיאה האלה בכותרות התגובה של HTTP/2 (מטא-נתונים). כברירת מחדל, ספריות הלקוח של gRPC מגבילות את הכותרות הנכנסות לגודל מקסימלי (בדרך כלל 8-10KB). אם פרטי השגיאה חורגים מהמגבלה הזו, ההעברה של HTTP/2 בצד הלקוח נכשלת לפני ניתוח התגובה לשגיאה, ומופיעה חריגה כמו:
Http2Exception: Header size exceeded max allowed size (10240)
הלקוח לא יכול לעבד את כותרות התגובה, ולכן הוא מבטל את הסטרימינג (שמופיע כסטטוס HTTP 499 Client Closed Request ביומנים בצד השרת), והאפליקציה לא יכולה לגשת לפרטי השגיאה BadRequest.
כדי לפתור את הבעיה ולבדוק את רשימת השגיאות המלאה, צריך להגדיר את לקוח ה-gRPC עם גודל מטא-נתונים מקסימלי גדול יותר (למשל 16MB):
.NET
// 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();
Java
// 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)) { // ... }
צומת
// 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) )
שיטות מומלצות לטיפול בשגיאות
כדי ליצור אפליקציות עמידות, כדאי ליישם את השיטות המומלצות הבאות.
- אימות לפני השליחה
- כשיוצרים או משנים שילוב, שולחים בקשות עם הערך
trueבשדהvalidateOnlyכדי לזהות שגיאות שגורמות לכשל מהיר לפני הטמעת הנתונים. - בדיקת פרטי השגיאה
- תמיד צריך לחפש את אחד ממטעני הייעודיים (payload) הסטנדרטיים של פרטים, כמו
BadRequest. כל מטען ייעודי (payload) של פרטים סטנדרטיים מכיל מידע שיעזור לכם להבין את הסיבה לשגיאה. - הבחנה בין שגיאות בצד הלקוח לשגיאות בחיבור לשרת
בודקים אם השגיאה נגרמה בגלל בעיה בהטמעה (הלקוח) או בגלל בעיה ב-API (השרת).
- שגיאות בצד הלקוח: קודים כמו
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), אל תנסו שוב מיד. להשהות את העיבוד עד שהמכסה היומית תתאפס בחצות, לפי שעון החוף המערבי של ארה"ב.
אתם צריכים להשתמש באלגוריתם של השהיה מעריכית לפני ניסיון חוזר (exponential backoff) כדי להמתין פרקי זמן הולכים וגדלים בין הניסיונות החוזרים. כך אפשר למנוע עומס יתר על שירות שכבר עמוס. לדוגמה, ממתינים שנייה אחת, אחר כך 2 שניות, אחר כך 4 שניות, עד שמגיעים למספר המקסימלי של ניסיונות חוזרים או לזמן ההמתנה הכולל.
הוסיפו כמות קטנה ואקראית של "רעידות" להשהיות של השהיית הניסיון החוזר, כדי למנוע את בעיית "העדר הרועם" שבה לקוחות רבים מנסים שוב בו-זמנית.
- תיעוד מפורט
מתעדים את תגובת השגיאה המלאה, כולל כל המטענים הייעודיים (payloads) של הפרטים הרגילים, במיוחד מזהה הבקשה. המידע הזה חיוני לניפוי באגים ולדיווח על בעיות לתמיכה של Google במקרה הצורך.
- שליחת משוב ממשתמשים
על סמך הקודים וההודעות במטעני הייעודי (payload) של הפרטים הסטנדרטיים, אתם יכולים לספק למשתמשים באפליקציה משוב ברור ומועיל. לדוגמה, במקום "אירעה שגיאה", אפשר לכתוב "מזהה העסקה חסר" או "מזהה החשבון של היעד לא נמצא".
אם תפעלו לפי ההנחיות האלה, תוכלו לאבחן ולטפל ביעילות בשגיאות שמוחזרות על ידי Data Manager API, וכך ליצור אפליקציות יציבות וידידותיות יותר למשתמש.