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
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, timeoutFangen 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:
APIConnectionError erbt direkt von ListingsAPIError und besitzt keines dieser Attribute; die Ausnahmemeldung beschreibt den Netzwerkfehler.
Ausnahmen abfangen
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:SY90005undSY90001lösenAuthenticationErroraus,SY90003löstPermissionDeniedErroraus,RATE_LIMITEDlöstRateLimitErroraus, und jeder andere Code löstAPIErroraus.- Antworten auf Schreiboperationen (Erstellen, Aktualisieren, Archivieren, Veröffentlichen von Beiträgen), die
success: falseoder eineerrors[]-Liste enthalten, lösenValidationErroraus.
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:
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():
namemuss 2 bis 150 Zeichen lang seindescriptionmuss mindestens 200 Zeichen lang seinsub_category_idist erforderlichcountry_isoist erforderlichcityist erforderlich, außer wennhide_address=Truegilt (Unternehmen mit Einzugsgebiet)
Für die Hilfsfunktionen für Beiträge:
nameist erforderlich undlocation_idsdarf nicht leer seinsitesmuss eine nicht leere Teilmenge vonGOOGLE,FACEBOOKseinmessageist erforderlich; bei einem dict mit Werten je Website benötigt jede Zielwebsite einen Textcta_typeundcta_urlmüssen gemeinsam angegeben werden, undcta_typemuss einen der WerteBOOK,ORDER,SHOP,LEARN_MORE,SIGN_UP,GET_OFFERhabentitleist 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:
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 callAutomatische 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:
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
# All exceptions from the top-level moduleimport listingsapi listingsapi.ListingsAPIErrorlistingsapi.APIErrorlistingsapi.AuthenticationErrorlistingsapi.PermissionDeniedErrorlistingsapi.NotFoundErrorlistingsapi.ValidationErrorlistingsapi.RateLimitErrorlistingsapi.InternalServerErrorlistingsapi.APIConnectionError # Or import individuallyfrom listingsapi import RateLimitError, ValidationErrorSiehe auch
- Konfiguration:
max_retriesundtimeout - Schnellstart: Ihr erstes Skript mit Fehlerbehandlung