คู่มือนี้อธิบายวิธีที่ Data Manager API จัดการและสื่อสารข้อผิดพลาด การทำความเข้าใจโครงสร้างและความหมายของข้อผิดพลาดของ API เป็นสิ่งสำคัญในการสร้าง แอปพลิเคชันที่มีประสิทธิภาพซึ่งสามารถจัดการปัญหาได้อย่างราบรื่น ตั้งแต่ข้อมูลที่ไม่ถูกต้องไปจนถึง บริการที่ไม่พร้อมใช้งานชั่วคราว
Data Manager API เป็นไปตามรูปแบบข้อผิดพลาดของ Google API มาตรฐาน ซึ่งอิงตามรหัสสถานะ gRPC การตอบกลับจาก API แต่ละรายการที่ทำให้เกิดข้อผิดพลาดจะมีออบเจ็กต์ Status ที่มีข้อมูลต่อไปนี้
- รหัสข้อผิดพลาดที่เป็นตัวเลข
- ข้อความแสดงข้อผิดพลาด
- รายละเอียดข้อผิดพลาดเพิ่มเติม (ไม่บังคับ)
รหัสข้อผิดพลาด Canonical
Data Manager API ใช้ชุดรหัสข้อผิดพลาดมาตรฐานที่กำหนดโดย gRPC และ HTTP รหัสเหล่านี้จะระบุประเภทข้อผิดพลาดในระดับสูง คุณควรตรวจสอบโค้ดนี้ก่อนเสมอเพื่อทำความเข้าใจลักษณะพื้นฐานของปัญหา
ดูรายละเอียดเพิ่มเติมเกี่ยวกับรหัสเหล่านี้ได้ที่คู่มือการออกแบบ API - รหัสข้อผิดพลาด
รูปแบบการลองผิดลองถูก
Data Manager API ใช้โมเดลการล้มเหลวอย่างรวดเร็ว หากคำขอมีข้อผิดพลาดทางโครงสร้าง หรือหากระเบียนใดก็ตามตรวจสอบความถูกต้องของฟิลด์ที่จำเป็นไม่สำเร็จ คำขอทั้งหมด จะล้มเหลว และ API จะไม่ประมวลผลข้อมูลใดๆ ในคำขอนั้น
การเปรียบเทียบกับโมเดลความล้มเหลวบางส่วน
รูปแบบการล้มเหลวอย่างรวดเร็วแตกต่างจากรูปแบบการล้มเหลวบางส่วนใน Google API อื่นๆ เช่น Google Ads API และ Campaign Manager 360 API ในรูปแบบความล้มเหลวบางส่วน คำขอจะสำเร็จแม้ว่าบางระเบียนจะมีข้อผิดพลาด และการตอบกลับจะมีรายละเอียดข้อผิดพลาดสำหรับระเบียนที่ไม่สำเร็จ
แม้ว่าการทำงานล้มเหลวบางส่วนจะสะดวก แต่ก็มีความเสี่ยงสูงเนื่องจากโมเดลการทำงานล้มเหลวบางส่วนไม่ได้แจ้งเตือนข้อผิดพลาดให้คุณล่วงหน้า คุณจึงต้องตรวจสอบข้อผิดพลาดในแต่ละคำตอบอย่างชัดเจน ซึ่งอาจซ่อนปัญหาสำคัญเนื่องจากคำขอจะสำเร็จแม้ว่า API จะปฏิเสธระเบียนจำนวนมากหรือทั้งหมดในคำขอก็ตาม หากส่วนสำคัญของบันทึกในคำขอมีข้อผิดพลาด แต่คุณไม่ได้ตรวจสอบการตอบกลับ คุณอาจไม่ทราบเลยว่าข้อมูลมีปัญหาในวงกว้าง และจะพบปัญหาเหล่านั้นในอีกหลายวันหรือหลายสัปดาห์ต่อมาเมื่อผลลัพธ์สะสมไม่เป็นไปตามที่คาดไว้
รูปแบบการล้มเหลวอย่างรวดเร็วจะหลีกเลี่ยงข้อผิดพลาดเหล่านี้โดยการแจ้งเตือนปัญหาเกี่ยวกับข้อมูลหรือการผสานรวมให้คุณทราบทันที เพื่อให้คุณดำเนินการที่เหมาะสมได้
ตรวจสอบข้อผิดพลาดแบบล้มเหลวอย่างรวดเร็วด้วย 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 รหัสข้อผิดพลาดจะอยู่ในฟิลด์
ตรวจสอบเพย์โหลดรายละเอียดมาตรฐานสำหรับรหัสข้อผิดพลาด เพย์โหลดรายละเอียดมาตรฐานคือชุดข้อความสำหรับข้อผิดพลาด จาก Google API โดยจะให้รายละเอียดข้อผิดพลาดในลักษณะที่มีโครงสร้างและสอดคล้องกัน ข้อผิดพลาดแต่ละรายการจาก Data Manager API อาจมีข้อความเพย์โหลดรายละเอียดมาตรฐานหลายรายการ ไลบรารีของไคลเอ็นต์ Data Manager API มีเมธอดตัวช่วยในการรับรายละเอียดมาตรฐาน เพย์โหลดจากข้อผิดพลาด
ไม่ว่ารหัสข้อผิดพลาดจะเป็นอะไร เราขอแนะนำให้คุณตรวจสอบและบันทึกเพย์โหลดของ
ErrorInfo,RequestInfo,HelpและLocalizedMessageErrorInfoมีข้อมูลที่อาจไม่อยู่ในเพย์โหลดอื่นๆRequestInfoมีรหัสคำขอ ซึ่งจะเป็นประโยชน์ในกรณีที่ต้องการติดต่อทีมสนับสนุนHelpและLocalizedMessageมีลิงก์และรายละเอียดอื่นๆ ที่จะช่วยคุณ แก้ไขข้อผิดพลาด
นอกจากนี้ เพย์โหลด
BadRequestยังมีประโยชน์สำหรับINVALID_ARGUMENTข้อผิดพลาด เนื่องจากมีข้อมูลเกี่ยวกับฟิลด์ที่ทำให้เกิดข้อผิดพลาด
คำเตือนการส่งผ่านข้อมูล
Data Manager API ยอมรับคำขอการนำเข้าให้ได้มากที่สุด หากคุณรวมข้อมูลที่ไม่จำเป็น การตรวจสอบช่องเหล่านั้นไม่สำเร็จ จะไม่ทำให้คำขอไม่สำเร็จ เช่น หากสินค้าในรถเข็นไม่มี รหัสสินค้าของผู้ขาย API จะประมวลผลคำขอที่เหลือและแสดง คำเตือน
การตอบกลับการส่งผ่านข้อมูลที่สําเร็จ (รหัสสถานะ HTTP 200) จะมีคําเตือนเหล่านี้
ในรายการ fieldWarnings แต่ละรายการคือออบเจ็กต์ FieldWarning ที่มีฟิลด์ต่อไปนี้
fieldตำแหน่งของฟิลด์ในคำขอในไวยากรณ์เส้นทางแบบ Snake Case
หากเส้นทางชี้ไปยังรายการในลิสต์ (ฟิลด์
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"
}
]
}
เพย์โหลดรายละเอียดมาตรฐาน
เพย์โหลดรายละเอียดมาตรฐานที่พบบ่อยที่สุดสำหรับ Data Manager API มีดังนี้
BadRequest
ตรวจสอบเพย์โหลด BadRequest เมื่อคำขอไม่สำเร็จโดยมี
INVALID_ARGUMENT (รหัสสถานะ HTTP 400)
ข้อความ BadRequest แสดงว่าคำขอมีฟิลด์ที่มีค่าไม่ถูกต้อง หรือไม่มีค่าสำหรับฟิลด์ที่จำเป็น
ดูfield_violationsรายการใน
BadRequestเพื่อดูว่าช่องใดมีข้อผิดพลาด แต่ละfield_violationsรายการ
มีข้อมูลที่จะช่วยคุณแก้ไขข้อผิดพลาด
fieldตำแหน่งของฟิลด์ในคำขอในไวยากรณ์เส้นทางแบบ Snake Case
หากเส้นทางชี้ไปยังรายการในลิสต์ (ฟิลด์
repeated) ดัชนีของเส้นทางจะแสดงในวงเล็บเหลี่ยม ([...]) หลังชื่อลิสต์เช่น
destinations[0].operating_account.account_idคือaccount_idในoperating_accountของรายการแรกในรายการdestinationsdescriptionคำอธิบายว่าเหตุใดค่าดังกล่าวจึงทำให้เกิดข้อผิดพลาด
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 รายการจะแสดงข้อผิดพลาด 2 รายการ ดังนี้
eventแรกมีค่าที่ไม่ได้เข้ารหัสฐานสิบหกในตัวระบุผู้ใช้ที่ 2 ของเหตุการณ์eventรายการที่ 2 มีค่าที่ไม่ได้เข้ารหัสฐาน 16 ในตัวระบุผู้ใช้ที่ 3 ของเหตุการณ์
{
"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 ที่ระบุคำขอ API ของคุณอย่างไม่ซ้ำกัน
{
"@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 - 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) เพย์โหลด 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 แสดง 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"
}
]
},
...
]
}
}
ดูรายละเอียดข้อผิดพลาดในการเข้าถึง
หากคุณใช้ไลบรารีของไคลเอ็นต์ ให้ใช้วิธีการช่วยเหลือเพื่อรับเพย์โหลดรายละเอียดมาตรฐาน
.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...
}
...
}
แนวทางปฏิบัติแนะนำในการจัดการข้อผิดพลาด
หากต้องการสร้างแอปพลิเคชันที่ยืดหยุ่น ให้ใช้แนวทางปฏิบัติแนะนำต่อไปนี้
- ตรวจสอบความถูกต้องก่อนส่ง
- เมื่อสร้างหรือเปลี่ยนการผสานรวม ให้ส่งคำขอโดยตั้งค่า
validateOnlyเป็นtrueเพื่อตรวจหาข้อผิดพลาดแบบล้มเหลวอย่างรวดเร็ว ก่อนที่จะส่งผ่านข้อมูล - ตรวจสอบรายละเอียดข้อผิดพลาด
- มองหาเพย์โหลดรายละเอียดมาตรฐานอย่างใดอย่างหนึ่งเสมอ เช่น
BadRequestเพย์โหลดรายละเอียดมาตรฐานแต่ละรายการมีข้อมูลที่จะช่วยให้คุณเข้าใจสาเหตุของข้อผิดพลาด - แยกความแตกต่างระหว่างข้อผิดพลาดของไคลเอ็นต์กับข้อผิดพลาดเกี่ยวกับเซิร์ฟเวอร์
พิจารณาว่าข้อผิดพลาดเกิดจากปัญหาในการติดตั้งใช้งาน (ไคลเอ็นต์) หรือปัญหาเกี่ยวกับ 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) ให้หยุดคำขอชั่วคราวและ ลองอีกครั้งโดยใช้ Exponential Backoff พร้อม Jitterหากขีดจำกัดเป็นรายวัน (เช่น
IngestionMutateRequestsPerDayPerProject) อย่าลองอีกครั้ง ทันที หยุดการประมวลผลชั่วคราวจนกว่าโควต้าประจำวันจะรีเซ็ตตอนเที่ยงคืนตามเวลาแปซิฟิก
ใช้อัลกอริทึม Exponential Backoff เพื่อรอระยะเวลาที่เพิ่มขึ้น ระหว่างการลองใหม่ ซึ่งจะช่วยไม่ให้บริการที่ทำงานหนักอยู่แล้ว ทำงานหนักยิ่งขึ้น เช่น รอ 1 วินาที แล้วรอ 2 วินาที จากนั้นรอ 4 วินาที โดยรอต่อไปจนกว่าจะถึง จำนวนการลองใหม่สูงสุดหรือเวลารอทั้งหมด
เพิ่ม "Jitter" จำนวนเล็กน้อยแบบสุ่มลงในระยะเวลาหน่วงของการหยุดชั่วคราวเพื่อป้องกันปัญหา "Thundering Herd" ที่ไคลเอ็นต์จำนวนมากพยายามอีกครั้งพร้อมกัน
- บันทึกอย่างละเอียด
บันทึกการตอบกลับข้อผิดพลาดทั้งหมด รวมถึงเพย์โหลดรายละเอียดมาตรฐานทั้งหมด โดยเฉพาะรหัสคำขอ ข้อมูลนี้มีความสำคัญอย่างยิ่งต่อการแก้ไขข้อบกพร่องและการรายงานปัญหาไปยังทีมสนับสนุนของ Google หากจำเป็น
- แสดงความคิดเห็นของผู้ใช้
ระบุความคิดเห็นที่ชัดเจนและเป็นประโยชน์แก่ผู้ใช้แอปพลิเคชันของคุณโดยอิงตามรหัสและข้อความในเพย์โหลดรายละเอียดมาตรฐาน เช่น แทนที่จะพูดว่า "เกิดข้อผิดพลาด" คุณสามารถพูดว่า "ไม่มีรหัสธุรกรรม" หรือ "ไม่พบรหัสบัญชี ของปลายทาง"
การทำตามหลักเกณฑ์เหล่านี้จะช่วยให้คุณวินิจฉัยและจัดการข้อผิดพลาดที่ API ของ Data Manager แสดงผลได้อย่างมีประสิทธิภาพ ซึ่งจะช่วยให้แอปพลิเคชันมีความเสถียรและใช้งานง่ายมากขึ้น