Penanganan galat

Hierarki pengecualian, atribut galat, galat payload HTTP 200, validasi sisi klien, dan panduan percobaan ulang untuk Python SDK Listings API.

Semua pengecualian dapat diimpor dari modul tingkat teratas listingsapi.

Hierarki pengecualian

Code
ListingsAPIError├── APIError                    API-reported failure: non-2xx, or an error payload in HTTP 200│   ├── AuthenticationError     401, or payload codes SY90005 / SY90001│   ├── PermissionDeniedError   403, or payload code SY90003│   ├── NotFoundError           404│   ├── ValidationError         400 / 422, mutation failures, client-side validation│   ├── RateLimitError          429, or payload code RATE_LIMITED (carries .retry_after)│   └── InternalServerError     5xx (safe to retry)└── APIConnectionError          network failure: DNS, connection refused, timeout

Tangkap ListingsAPIError untuk menangani semua pengecualian yang dapat dimunculkan SDK, APIError untuk semua kesalahan yang dilaporkan API, atau subkelas tertentu untuk penanganan khusus.

Atribut pengecualian

APIError dan subkelasnya memiliki:

AtributTipeDeskripsi
status_codeint | NoneKode status HTTP (dapat berupa 200 untuk kesalahan pada tingkat payload)
codestr | NoneKode kesalahan platform pertama, e.g. SY10005
errorslist[dict]Entri kesalahan yang telah dinormalisasi, masing-masing berupa {"code", "message", "context"}
response_bodystr | NoneTeks respons mentah dari API
retry_afterfloat | NoneHanya untuk RateLimitError; diurai dari header Retry-After

APIConnectionError mewarisi langsung dari ListingsAPIError dan tidak memiliki satu pun atribut ini; pesan pengecualiannya menjelaskan kegagalan jaringan.

Menangkap pengecualian

Python
import listingsapi client = listingsapi.ListingsAPI() try:  location = client.locations.retrieve(16808)except listingsapi.AuthenticationError as e:  print("Invalid API key:", e.code)except listingsapi.PermissionDeniedError as e:  print("Not allowed:", e.status_code)except listingsapi.NotFoundError as e:  print("No such location:", e.status_code)except listingsapi.ValidationError as e:  for err in e.errors:      print(err["code"], err["message"], err["context"])except listingsapi.RateLimitError as e:  print("Rate limited, retry in", e.retry_after, "seconds")except listingsapi.InternalServerError as e:  print("Server error (safe to retry):", e.status_code)except listingsapi.APIConnectionError as e:  print("Network failure:", e)except listingsapi.APIError as e:  print("Unexpected API error:", e.status_code, e.code, e.response_body)

Kesalahan dalam respons HTTP 200

Platform terkadang melaporkan kegagalan di dalam isi respons 200. SDK memeriksa setiap respons dan memunculkan pengecualian, sehingga Anda tidak perlu memeriksa flag success atau menelusuri array errors sendiri:

  • Isi errors[] tingkat teratas dipetakan berdasarkan kode: SY90005 dan SY90001 memunculkan AuthenticationError, SY90003 memunculkan PermissionDeniedError, RATE_LIMITED memunculkan RateLimitError, dan kode lainnya memunculkan APIError.
  • Respons operasi tulis (pembuatan, pembaruan, pengarsipan, penerbitan postingan) yang berisi success: false atau daftar errors[] memunculkan ValidationError.

Dalam kedua kasus tersebut, status_code adalah status HTTP yang sebenarnya (sering kali 200), code adalah kode platform pertama, dan errors berisi semua entri yang telah dinormalisasi:

Python
import listingsapi client = listingsapi.ListingsAPI() try:  result = client.locations.update({"id": 16808, "phone": "not-a-phone"})except listingsapi.ValidationError as e:  print(e.status_code)   # 200: the API accepted the request but rejected the mutation  print(e.code)          # first platform code, e.g. "SY10005"  for err in e.errors:      print(err["code"], err["message"], err["context"])

Validasi di sisi klien

locations.add() dan fungsi bantu postingan (posts.create_announcement(), posts.create_event(), posts.create_offer(), posts.bulk_publish()) memvalidasi payload secara lokal dan memunculkan ValidationError sebelum panggilan jaringan apa pun, sehingga payload yang tidak valid segera menghasilkan kegagalan dengan pesan yang jelas tanpa harus mengirim permintaan dan menunggu respons.

Untuk locations.add():

  • name harus terdiri dari 2 hingga 150 karakter
  • description harus terdiri dari setidaknya 200 karakter
  • sub_category_id wajib diisi
  • country_iso wajib diisi
  • city wajib diisi kecuali hide_address=True (bisnis dengan area layanan)

Untuk fungsi bantu postingan:

  • name wajib diisi dan location_ids tidak boleh kosong
  • sites harus berupa subset yang tidak kosong dari GOOGLE, FACEBOOK
  • message wajib diisi; jika berupa dict per situs, setiap situs tujuan harus memiliki teks
  • cta_type dan cta_url harus diberikan bersama, dan cta_type harus berupa salah satu dari BOOK, ORDER, SHOP, LEARN_MORE, SIGN_UP, GET_OFFER
  • title wajib diisi untuk acara dan penawaran

Pada kesalahan yang dimunculkan secara lokal ini, status_code, code, dan response_body bernilai None, sedangkan errors kosong; str(e) mencantumkan semua masalah yang ditemukan:

Python
import listingsapi client = listingsapi.ListingsAPI() try:  client.locations.add(      name="Acme Dental",      description="Too short.",      sub_category_id=1432,      country_iso="US",      city="New York",  )except listingsapi.ValidationError as e:  print(e)  # Invalid location: description must be at least 200 characters (got 10)  print(e.status_code)  # None: raised before any network call

Percobaan ulang otomatis

SDK secara otomatis mencoba ulang 429, 500, 502, 503, dan 504 untuk GET, HEAD, dan OPTIONS (secara default 2 kali percobaan ulang, faktor penundaan eksponensial 0.5 detik, Retry-After dipatuhi). Operasi tulis tidak dicoba ulang: POST atau DELETE dikirim sekali dan memunculkan pengecualian pada kegagalan pertama. Atur melalui argumen konstruktor max_retries; lihat Konfigurasi.

API v4 tidak mendukung Idempotency-Key dan tidak mendeteksi operasi tulis berulang, sehingga operasi tulis yang melewati batas waktu atau mengembalikan 5xx mungkin sudah tersimpan. Mencobanya ulang tanpa pemeriksaan akan membuat lokasi, postingan, atau balasan ulasan kedua. Baca kembali rekaman menggunakan kunci yang Anda kendalikan sebelum mengulangi operasi tulis.

Memberi jeda saat terjadi RateLimitError

Jika 429 masih terjadi setelah percobaan ulang bawaan, RateLimitError.retry_after berisi nilai Retry-After dari server dalam detik (atau None jika header tidak ada). Pola sederhana untuk tugas batch:

Python
import randomimport time import listingsapi client = listingsapi.ListingsAPI(max_retries=0)  # manual retry control def with_backoff(call, max_attempts=5):  for attempt in range(max_attempts):      try:          return call()      except listingsapi.RateLimitError as e:          if attempt == max_attempts - 1:              raise          if e.retry_after is not None:              delay = e.retry_after          else:              delay = min(2 ** attempt, 30) + random.random()          time.sleep(delay) page = with_backoff(lambda: client.locations.list(first=50))for location in page:  print(location.name)

Mengimpor pengecualian

Python
# All exceptions from the top-level moduleimport listingsapi listingsapi.ListingsAPIErrorlistingsapi.APIErrorlistingsapi.AuthenticationErrorlistingsapi.PermissionDeniedErrorlistingsapi.NotFoundErrorlistingsapi.ValidationErrorlistingsapi.RateLimitErrorlistingsapi.InternalServerErrorlistingsapi.APIConnectionError # Or import individuallyfrom listingsapi import RateLimitError, ValidationError

Lihat juga