錯誤回應

標準錯誤回應

如果 Tag Manager API 要求成功,API 會在回應主體中傳回 200 HTTP 狀態碼,以及所要求的資料。

如果要求發生錯誤,API 會在回應中根據錯誤類型傳回 HTTP 狀態碼和原因。此外,回應主體會包含錯誤原因的詳細說明。錯誤回應的範例如下:

400 invalidParameter

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "accessNotConfigured",
    "message": "Access Not Configured. Please use Google Developers Console to activate the API for your project.",
   }
  ],
  "code": 403,
  "message": "Access Not Configured. Please use Google Developers Console to activate the API for your project."
 }
}

注意:說明內容隨時可能變更,因此應用程式不應取決於實際說明文字。

實行指數輪詢

指數輪詢是指用戶端定期重試失敗要求的程序。是網路應用程式的標準錯誤處理策略。Tag Manager API 的設計考量,如果用戶端選擇以指數輪詢方式重試失敗的要求,即會達到這個目的。除了「必要」外,使用指數輪詢還能提升頻寬用量的效率、減少取得成功回應所需的要求數量,並盡可能提高並行環境中的要求處理量。

實作簡易指數輪詢的流程如下。

  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」n會增加 1。

演算法設定為在 n 為 5 時終止。這個上限是為了防止用戶端無限重試。因此,總延遲時間約為 32 秒,之後系統就會將要求視為「無法復原的錯誤」。

下列 Python 程式碼是上述流程的實作,用於從名為 makeRequest 的方法中復原的錯誤。

import random
import time
from apiclient.errors import HttpError

def makeRequestWithExponentialBackoff(tagmanager):
  """Wrapper to request Google Tag Manager data with exponential backoff.

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

  Args:
    tagmanager: The tagmanager service object

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

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

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