Fehlerbehandlung
Caching und Monitoring: Caching & Monitoring.
Plattformfehler (401, 403, 422, 429, 5xx, Wiederholungsversuche/Backoff, Rate-Limit-Header): Fehlerbehandlung.
Luftfahrzeugabfrage: found ist kein 404
Der Endpoint für Kennzeichen gibt immer 200 zurück, wenn die Anfrage selbst gültig ist — auch dann, wenn das Kennzeichen nicht im Luftfahrzeugregister von SkyLink enthalten ist. Behandeln Sie ein fehlendes Luftfahrzeug nicht als HTTP-Fehler.
| Situation | HTTP-Status | Erkennung |
|---|---|---|
| Kennzeichen bekannt | 200 | found: true |
| Kennzeichen unbekannt | 200 | found: false |
| Fehlerhaftes Pfadsegment | 404 | HTTP-Statuscode |
Prüfen Sie immer found, bevor Sie aircraft.*-Felder lesen. Das Lesen von aircraft.icao_type in einer Antwort mit found: false löst einen KeyError aus.
Flugleistungsdaten: 422 bei unbekanntem Typ
GET /aircraft/performance/{icao_type} gibt 422 zurück, wenn der ICAO-Typcode nicht erkannt wird. Das ist ein normales Ergebnis, wenn Sie an eine Registerabfrage anknüpfen: Nicht jeder icao_type-Wert im Register hat einen entsprechenden Leistungsdatensatz.
| Antwort | Bedeutung |
|---|---|
200 | Leistungsdaten zurückgegeben |
422 | Typcode nicht in der Leistungsdatenbank — mit Fallback weiterarbeiten |
Live-ADS-B: leeres aircraft[] ist kein Fehler
GET /adsb/aircraft gibt 200 mit aircraft: [] zurück, wenn kein Luftfahrzeug dem angefragten Filter (Radius, Bbox oder Rufzeichen) entspricht. Das ist ein gültiges leeres Ergebnis — zeigen Sie kein Fehlerbanner an. Der Feed ist live; Luftfahrzeuge bewegen sich innerhalb von Sekunden in Ihren Filterbereich hinein und wieder heraus.
Außerdem gilt: Cachen Sie niemals Live-ADS-B-Antworten. Der Feed wird alle paar Sekunden aktualisiert; eine gecachte Position ist bereits veraltet, wenn das nächste Rendering erfolgt.
Historische ADS-B-Daten: Tarifbeschränkungen und Zeitraumfehler
Die /ultra/history/...-Endpoints erfordern den Tarif Pro oder höher. Eine Antwort mit 401 oder 403 enthält einen message-Schlüssel, der die Einschränkung erklärt — zeigen Sie diese Meldung an statt eines allgemeinen Textes wie „Zugriff verweigert“.
Der Endpoint /ultra/history/airport/{icao}/traffic erfordert den korrekten direction-Wert:
| Korrekt | Falsch |
|---|---|
direction=arr | direction=arrivals |
direction=dep | direction=departures |
Der Such-Endpoint /ultra/history/flights gibt 422 zurück, wenn der angefragte Zeitraum die maximale Aufbewahrungsdauer des Pfads überschreitet (90 Tage bei /ultra/...). Verkleinern Sie den Zeitraum und versuchen Sie es erneut.
import os
import requests
HEADERS = {
"X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
"X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"
def lookup_registration(registration: str) -> dict | None:
"""
Returns aircraft dict or None when not found.
Always checks the `found` field — never treats found=false as an error.
"""
r = requests.get(
f"{BASE}/aircraft/registration/{registration}",
headers=HEADERS,
timeout=(10, 15),
)
r.raise_for_status()
data = r.json()
if not data.get("found"):
print(f"Registration {registration} not in registry (found=false).")
return None
return data["aircraft"]
def fetch_performance(icao_type: str) -> dict | None:
"""
Returns performance data or None on 422 (type not in database).
"""
r = requests.get(
f"{BASE}/aircraft/performance/{icao_type}",
headers=HEADERS,
timeout=(10, 15),
)
if r.status_code == 422:
print(f"Performance data not available for type {icao_type!r} (422).")
return None
r.raise_for_status()
return r.json()
def fetch_history_with_plan_gate(registration: str) -> list[dict] | None:
"""
Fetches recent historical flights. Surfaces the plan gate message on 401/403.
"""
r = requests.get(
f"{BASE}/ultra/history/flights",
headers=HEADERS,
params={"registration": registration, "limit": 5},
timeout=(10, 25),
)
if r.status_code in (401, 403):
msg = r.json().get("message", "Plan not entitled.")
print(f"Access denied: {msg}")
print("Upgrade to Pro or above for /ultra/history/... endpoints.")
return None
r.raise_for_status()
return r.json().get("flights", [])
def main() -> None:
# 1. Registration lookup — check found field
ac = lookup_registration("N636JB")
if ac:
print(f"Found: {ac['registration']} / {ac['icao_type']} / {ac['owner_operator']}")
# 2. Chain to performance — handle 422
perf = fetch_performance(ac["icao_type"])
if perf:
print(f"Cruise speed: {perf.get('cruise_speed_ktas')} kt")
else:
print("Showing registration data only — no performance record.")
else:
print("Show empty state to user — aircraft not in registry.")
# 3. Historical search — handle 401/403 plan gate
flights = fetch_history_with_plan_gate("N636JB")
if flights is not None:
print(f"Last {len(flights)} archived flights retrieved.")
if __name__ == "__main__":
main()Für Antworten mit 429 und 5xx verwenden Sie die Hilfsfunktion für Wiederholungsversuche unter Fehlerbehandlung.
Siehe auch: Luftfahrzeugabfrage · Flugleistungsdaten · ADS-B · Historische ADS-B-Daten · Muster für den Produktivbetrieb