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

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

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

การจัดการกับคำตอบ 500 หรือ 503

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

การติดตั้งใช้งาน 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."