Fehlerbehandlung

Ausnahmehierarchie, Fehlerattribute, Fehler in HTTP-200-Nutzdaten, clientseitige Validierung und Wiederholungshinweise für das Listings API Python SDK.

Alle Ausnahmen können aus dem Modul listingsapi auf oberster Ebene importiert werden.

Ausnahmehierarchie

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

Fangen Sie ListingsAPIError ab, um alle vom SDK ausgelösten Ausnahmen zu behandeln, APIError für alle von der API gemeldeten Fehler oder eine bestimmte Unterklasse für eine gezielte Behandlung.

Attribute der Ausnahmen

APIError und seine Unterklassen enthalten:

AttributTypBeschreibung
status_codeint | NoneHTTP-Statuscode (kann bei Fehlern auf Payload-Ebene 200 sein)
codestr | NoneErster Fehlercode der Plattform, e.g. SY10005
errorslist[dict]Normalisierte Fehlereinträge, jeweils {"code", "message", "context"}
response_bodystr | NoneUnverarbeiteter Antworttext der API
retry_afterfloat | NoneNur bei RateLimitError; aus dem Header Retry-After ausgelesen

APIConnectionError erbt direkt von ListingsAPIError und besitzt keines dieser Attribute; die Ausnahmemeldung beschreibt den Netzwerkfehler.

Ausnahmen abfangen

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)

Fehler in HTTP-200-Antworten

Die Plattform meldet Fehler manchmal im Antwortinhalt einer 200-Antwort. Das SDK prüft jede Antwort und löst bei Fehlern eine Ausnahme aus, sodass Sie weder success-Flags selbst prüfen noch errors-Arrays selbst durchsuchen müssen:

  • errors[]-Antwortinhalte auf oberster Ebene werden anhand des Codes zugeordnet: SY90005 und SY90001 lösen AuthenticationError aus, SY90003 löst PermissionDeniedError aus, RATE_LIMITED löst RateLimitError aus, und jeder andere Code löst APIError aus.
  • Antworten auf Schreiboperationen (Erstellen, Aktualisieren, Archivieren, Veröffentlichen von Beiträgen), die success: false oder eine errors[]-Liste enthalten, lösen ValidationError aus.

In beiden Fällen ist status_code der tatsächliche HTTP-Status (oft 200), code der erste Plattformcode, und errors enthält alle normalisierten Einträge:

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"])

Clientseitige Validierung

locations.add() und die Hilfsfunktionen für Beiträge (posts.create_announcement(), posts.create_event(), posts.create_offer(), posts.bulk_publish()) validieren ihre Payload lokal und lösen ValidationError vor jedem Netzwerkaufruf aus, sodass eine ungültige Payload sofort mit einer klaren Meldung abgelehnt wird, ohne eine Anfrage zu senden und auf die Antwort zu warten.

Für locations.add():

  • name muss 2 bis 150 Zeichen lang sein
  • description muss mindestens 200 Zeichen lang sein
  • sub_category_id ist erforderlich
  • country_iso ist erforderlich
  • city ist erforderlich, außer wenn hide_address=True gilt (Unternehmen mit Einzugsgebiet)

Für die Hilfsfunktionen für Beiträge:

  • name ist erforderlich und location_ids darf nicht leer sein
  • sites muss eine nicht leere Teilmenge von GOOGLE, FACEBOOK sein
  • message ist erforderlich; bei einem dict mit Werten je Website benötigt jede Zielwebsite einen Text
  • cta_type und cta_url müssen gemeinsam angegeben werden, und cta_type muss einen der Werte BOOK, ORDER, SHOP, LEARN_MORE, SIGN_UP, GET_OFFER haben
  • title ist für Veranstaltungen und Angebote erforderlich

Bei diesen lokal ausgelösten Fehlern haben status_code, code und response_body den Wert None, und errors ist leer; str(e) listet alle gefundenen Probleme auf:

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

Automatische Wiederholungsversuche

Das SDK wiederholt Anfragen bei 429, 500, 502, 503 und 504 automatisch für GET, HEAD und OPTIONS (standardmäßig 2 Wiederholungsversuche, exponentieller Backoff-Faktor von 0,5 Sekunden, Retry-After wird berücksichtigt). Schreiboperationen werden nicht wiederholt: Eine POST- oder DELETE-Anfrage wird einmal gesendet und löst beim ersten Fehler eine Ausnahme aus. Konfigurieren Sie dies über das Konstruktorargument max_retries; siehe Konfiguration.

Die v4-API unterstützt Idempotency-Key nicht und erkennt keine wiederholten Schreiboperationen, sodass eine Schreiboperation, bei der eine Zeitüberschreitung auftritt oder die 5xx zurückgibt, bereits gespeichert worden sein kann. Eine ungeprüfte Wiederholung würde einen zweiten Standort, einen zweiten Beitrag oder eine zweite Antwort auf eine Bewertung erstellen. Lesen Sie den Datensatz anhand eines von Ihnen kontrollierten Schlüssels erneut aus, bevor Sie eine Schreiboperation wiederholen.

Wartezeiten bei RateLimitError

Wenn nach den integrierten Wiederholungsversuchen weiterhin 429 auftritt, enthält RateLimitError.retry_after den Retry-After-Wert des Servers in Sekunden (oder None, wenn der Header fehlte). Ein einfaches Vorgehen für Stapelverarbeitungsaufgaben:

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)

Ausnahmen importieren

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

Siehe auch