การตอบกลับข้อผิดพลาด

การตอบกลับข้อผิดพลาดมาตรฐาน

หากคำขอ Core Reporting API สําเร็จ API จะแสดงรหัสสถานะ 200 หากข้อผิดพลาดเกิดขึ้นกับคำขอ API จะแสดงรหัสสถานะ HTTP, สถานะ และเหตุผลในการตอบกลับตามประเภทของข้อผิดพลาด นอกจากนี้ ส่วนเนื้อหาของการตอบกลับจะมีคำอธิบายโดยละเอียดเกี่ยวกับสาเหตุที่ทำให้เกิดข้อผิดพลาด ต่อไปนี้คือตัวอย่างการตอบกลับข้อผิดพลาด

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "invalidParameter",
    "message": "Invalid value '-1' for max-results. Value must be within the range: [1, 1000]",
    "locationType": "parameter",
    "location": "max-results"
   }
  ],
  "code": 400,
  "message": "Invalid value '-1' for max-results. Value must be within the range: [1, 1000]"
 }
}

ตารางข้อผิดพลาด

รหัส เหตุผล คำอธิบาย การดำเนินการที่แนะนำ
400 invalidParameter ระบุว่าพารามิเตอร์คำขอมีค่าที่ไม่ถูกต้อง ช่อง locationType และ location ในการตอบกลับข้อผิดพลาดให้ข้อมูลว่าค่าใดไม่ถูกต้อง อย่าลองอีกครั้งโดยไม่แก้ไขปัญหา คุณต้องระบุค่าที่ถูกต้องสำหรับพารามิเตอร์ที่ระบุไว้ในการตอบกลับข้อผิดพลาด
400 badRequest บ่งบอกว่าการค้นหาไม่ถูกต้อง เช่น ไม่มีรหัสหลัก หรือชุดค่าผสมของมิติข้อมูลหรือเมตริกที่ขอไม่ถูกต้อง อย่าลองอีกครั้งโดยไม่แก้ไขปัญหา คุณต้องทำการเปลี่ยนแปลงกับการค้นหา API เพื่อให้การค้นหา API ทำงานได้
401 invalidCredentials ระบุว่าโทเค็นการตรวจสอบสิทธิ์ไม่ถูกต้องหรือหมดอายุแล้ว อย่าลองอีกครั้งโดยไม่แก้ไขปัญหา คุณจำเป็นต้องรับโทเค็นการตรวจสอบสิทธิ์ใหม่
403 insufficientPermissions ระบุว่าผู้ใช้มีสิทธิ์ไม่เพียงพอสำหรับเอนทิตีที่ระบุในการค้นหา อย่าลองอีกครั้งโดยไม่แก้ไขปัญหา คุณต้องได้รับสิทธิ์ที่เพียงพอเพื่อดำเนินการกับเอนทิตีที่ระบุ
403 dailyLimitExceeded ระบุว่าผู้ใช้ใช้งานเกินโควต้ารายวัน (ต่อโปรเจ็กต์หรือต่อข้อมูลพร็อพเพอร์ตี้ (โปรไฟล์)) อย่าลองอีกครั้งโดยไม่แก้ไขปัญหา คุณใช้โควต้ารายวันหมดแล้ว โปรดดูขีดจำกัดและโควต้า API
403 userRateLimitExceeded ระบุว่าเกินขีดจำกัดของข้อความค้นหาต่อ 100 วินาทีต่อผู้ใช้แล้ว ค่าเริ่มต้นที่กำหนดในคอนโซล Google API คือการค้นหา 100 รายการต่อ 100 วินาทีต่อผู้ใช้ คุณสามารถเพิ่มขีดจํากัดนี้ในคอนโซล Google API เป็นได้สูงสุด 1,000 รายการ ลองอีกครั้งโดยใช้ Exponential Backoff คุณจะต้องชะลอความเร็วในการส่งคำขอ
403 rateLimitExceeded ระบุว่าโปรเจ็กต์ใช้อัตราการค้นหาต่อ 100 วินาทีเกินขีดจำกัดแล้ว ลองอีกครั้งโดยใช้ Exponential Backoff คุณจะต้องชะลอความเร็วในการส่งคำขอ
403 quotaExceeded ระบุว่าถึงคําขอพร้อมกัน 10 คําขอต่อข้อมูลพร็อพเพอร์ตี้ (โปรไฟล์) ใน Core Reporting API แล้ว ลองอีกครั้งโดยใช้ Exponential Backoff คุณต้องรอคำขอที่อยู่ระหว่างดำเนินการอย่างน้อย 1 รายการเพื่อให้ข้อมูลพร็อพเพอร์ตี้ (โปรไฟล์) นี้เสร็จสมบูรณ์
500 internalServerError เกิดข้อผิดพลาดที่ไม่คาดคิดกับเซิร์ฟเวอร์ อย่าลองใช้คำค้นหานี้ซ้ำมากกว่า 1 ครั้ง
503 backendError เซิร์ฟเวอร์แสดงผลข้อผิดพลาด อย่าลองใช้คำค้นหานี้ซ้ำมากกว่า 1 ครั้ง

การจัดการคำตอบประเภท 500 หรือ 503

ข้อผิดพลาด 500 หรือ 503 อาจส่งผลให้เกิดระหว่างการใช้งานหนักหรือสำหรับคำขอที่ซับซ้อนมากขึ้น สำหรับคำขอจำนวนมาก ให้ลองขอข้อมูลสำหรับระยะเวลาที่สั้นลง นอกจากนี้ ให้พิจารณาใช้งาน Exponential Backoff ด้วย ความถี่ของข้อผิดพลาดเหล่านี้จะขึ้นอยู่กับข้อมูลพร็อพเพอร์ตี้ (โปรไฟล์) และปริมาณข้อมูลการรายงานที่เกี่ยวข้องกับข้อมูลพร็อพเพอร์ตี้นั้น คำค้นหาที่ทำให้เกิดข้อผิดพลาด 500 หรือ 503 สำหรับข้อมูลพร็อพเพอร์ตี้ (โปรไฟล์) 1 รายการไม่ได้ทำให้เกิดข้อผิดพลาดกับคำค้นหาเดียวกันด้วยข้อมูลพร็อพเพอร์ตี้ (โปรไฟล์) อื่น

การใช้ Exponential Backoff

Exponential Backoff คือกระบวนการของไคลเอ็นต์ในการส่งคำขอที่ล้มเหลวซ้ำเป็นระยะๆ เป็นระยะเวลาที่เพิ่มขึ้น ซึ่งก็คือกลยุทธ์การจัดการข้อผิดพลาดมาตรฐานสำหรับแอปพลิเคชันเครือข่าย Core Reporting API ออกแบบมาโดยคาดหวังให้ไคลเอ็นต์ที่เลือกที่จะลองส่งคำขอที่ล้มเหลวอีกครั้ง ระบบจะดำเนินการดังกล่าวโดยใช้ Exponential Backoff นอกจากจะ "จำเป็น" แล้ว การใช้ Exponential Backoff จะช่วยเพิ่มประสิทธิภาพของการใช้งานแบนด์วิดท์ ลดจำนวนคำขอที่ต้องใช้เพื่อให้การตอบสนองประสบความสำเร็จ และเพิ่มอัตราการส่งข้อมูลของคำขอในสภาพแวดล้อมที่เกิดขึ้นพร้อมกันให้ได้มากที่สุด

ขั้นตอนในการใช้งาน Exponential Backoff อย่างง่ายมีดังนี้

  1. ส่งคำขอไปยัง API
  2. รับการตอบกลับข้อผิดพลาดซึ่งมีรหัสข้อผิดพลาดที่ลองใหม่ได้
  3. รอ 1 วินาที + random_number_milliseconds วินาที
  4. ลองส่งคำขออีกครั้ง
  5. รับการตอบกลับข้อผิดพลาดซึ่งมีรหัสข้อผิดพลาดที่ลองใหม่ได้
  6. รอ 2 วินาที + random_number_milliseconds วินาที
  7. ลองส่งคำขออีกครั้ง
  8. รับการตอบกลับข้อผิดพลาดซึ่งมีรหัสข้อผิดพลาดที่ลองใหม่ได้
  9. รอ 4 วินาที + random_number_milliseconds วินาที
  10. ลองส่งคำขออีกครั้ง
  11. รับการตอบกลับข้อผิดพลาดซึ่งมีรหัสข้อผิดพลาดที่ลองใหม่ได้
  12. รอ 8 วินาที + random_number_milliseconds วินาที
  13. ลองส่งคำขออีกครั้ง
  14. รับการตอบกลับข้อผิดพลาดซึ่งมีรหัสข้อผิดพลาดที่ลองใหม่ได้
  15. รอ 16 วินาที + random_number_milliseconds วินาที
  16. ลองส่งคำขออีกครั้ง
  17. หากยังพบข้อผิดพลาด ให้หยุดและบันทึกข้อผิดพลาดนั้น

ในขั้นตอนข้างต้น random_number_milliseconds เป็นตัวเลขแบบสุ่มของมิลลิวินาทีที่น้อยกว่าหรือเท่ากับ 1, 000 ซึ่งจําเป็นเพื่อหลีกเลี่ยงข้อผิดพลาดในการล็อกบางประการในการใช้งานพร้อมกันบางรายการ ต้องกำหนด random_number_milliseconds ใหม่หลังจากรอแต่ละครั้ง

หมายเหตุ: การรอจะเป็น (2 ^ n) + random_number_milliseconds เสมอ โดย n คือจำนวนเต็มที่เพิ่มขึ้นแบบตายตัวซึ่งในตอนแรกกำหนดเป็น 0.n แล้วเพิ่มขึ้นทีละ 1 สำหรับแต่ละการทำซ้ำ (คำขอแต่ละรายการ)

อัลกอริทึมตั้งค่าให้สิ้นสุดเมื่อ n เท่ากับ 5 เพดานนี้มีไว้เพื่อหยุดไม่ให้ไคลเอ็นต์ลองอีกครั้งแบบไม่จำกัดเท่านั้น และจะทำให้เกิดความล่าช้าโดยรวมประมาณ 32 วินาทีก่อนที่คำขอจะถือว่าเป็น "ข้อผิดพลาดที่กู้คืนไม่ได้"

โค้ด Python ต่อไปนี้คือการใช้โฟลว์ข้างต้นเพื่อกู้คืนจากข้อผิดพลาดที่เกิดขึ้นในเมธอดชื่อ makeRequest

import random
import time
from apiclient.errors import HttpError

def makeRequestWithExponentialBackoff(analytics):
  """Wrapper to request Google Analytics data with exponential backoff.

  The makeRequest method accepts the analytics service object, makes API
  requests and returns the response. If any error occurs, the makeRequest
  method is retried using exponential backoff.

  Args:
    analytics: The analytics service object

  Returns:
    The API response from the makeRequest method.
  """
  for n in range(0, 5):
    try:
      return makeRequest(analytics)

    except HttpError, error:
      if error.resp.reason in ['userRateLimitExceeded', 'quotaExceeded',
                               'internalServerError', 'backendError']:
        time.sleep((2 ** n) + random.random())
      else:
        break

  print "There has been an error, the request never succeeded."