# Fehlerbehandlung

Fehler der Ticketsuche im Produktivbetrieb behandeln — keine Ergebnisse, ungültige Routen und Validierungsfehler.



Caching und Monitoring: [Caching & Monitoring](/docs/v31/tickets-integration-production).

**Plattformfehler** (401, 403, 422, 429, 5xx, Wiederholungsversuche/Backoff, Rate-Limit-Header): [Fehlerbehandlung](/docs/errors).

### Leere Ergebnisse sind keine Fehler [#empty-results-are-not-errors]

`count: 0` mit `flights: []` ist eine **gültige** Antwort. Sie bedeutet, dass für die angefragte Reiseroute an diesem Datum keine Plätze gefunden wurden — kein Client-Bug und kein Serverausfall. Zeigen Sie in der UI einen Zustand „keine Verfügbarkeit“ statt eines Fehlerbanners an.

```json
{
  "origin": "JFK",
  "destination": "LAX",
  "date": "2026-08-14",
  "passengers": 1,
  "count": 0,
  "flights": []
}
```

| Status                | Bedeutung                | Reaktion der UI                                                                      |
| --------------------- | ------------------------ | ------------------------------------------------------------------------------------ |
| `200` mit `count > 0` | Ergebnisse verfügbar     | Flugliste anzeigen                                                                   |
| `200` mit `count: 0`  | Keine Verfügbarkeit      | „Keine Flüge für diese Route und dieses Datum gefunden.“ anzeigen                    |
| `422`                 | Ungültige Parameter      | Anfrage korrigieren — nicht an Passagiere weitergeben                                |
| `429`                 | Rate Limit überschritten | Backoff und erneuter Versuch — siehe [Retry-Hilfsfunktion](/docs/errors#retry-rules) |

### Nur IATA-Codes [#iata-codes-only]

Dieser Endpoint akzeptiert **dreistellige IATA-Codes** (`JFK`, `LAX`, `LHR`) — keine ICAO-Codes. Die Übergabe eines vierstelligen ICAO-Codes (`KJFK`) liefert einen `422`. Lösen Sie Codes zuerst mit der [Flughafensuche](/docs/v31/airport-search) auf.

### 422 — Validierungsfehler [#422--validation-errors]

Wird zurückgegeben, wenn `origin` oder `destination` fehlen, leer sind oder die Prüfung des IATA-Formats nicht bestehen.

| Feld          | Häufige Ursache                                                                             |
| ------------- | ------------------------------------------------------------------------------------------- |
| `origin`      | Fehlt, ist leer, oder es wurde ein vierstelliger ICAO-Code statt eines IATA-Codes übergeben |
| `destination` | Wie oben                                                                                    |
| `passengers`  | Wert außerhalb des Bereichs 1–9                                                             |

### Preise sind Richtwerte [#prices-are-indicative]

Angebote spiegeln eine Momentaufnahme des Marktes zum Zeitpunkt der Suche wider, nicht das Live-Inventar der Fluggesellschaften. Angezeigte Plätze können zwischen Suche und Buchung ausverkauft sein oder sich im Preis ändern. **Weisen Sie Passagiere darauf hin** — in jeder UI, die Preise anzeigt (zum Beispiel: „Preise können sich bei der Buchung ändern“).

```python
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 search_tickets(
    origin: str,
    destination: str,
    date: str | None = None,
    passengers: int = 1,
) -> dict:
    """
    Search tickets. Returns the full response dict including count and flights.
    Raises ValueError on 422. Returns count:0/flights:[] for no availability.
    """
    params: dict[str, str | int] = {
        "origin": origin,
        "destination": destination,
        "passengers": passengers,
    }
    if date:
        params["date"] = date

    r = requests.get(
        f"{BASE}/tickets/search",
        headers=HEADERS,
        params=params,
        timeout=(10, 15),
    )
    if r.status_code == 422:
        detail = r.json().get("detail", "validation error")
        raise ValueError(f"422 Unprocessable: {detail}")
    r.raise_for_status()
    return r.json()


def display_results(data: dict) -> None:
    flights = data.get("flights", [])
    origin = data.get("origin", "?")
    dest = data.get("destination", "?")

    if not flights:
        # count:0 is valid — show a user-friendly empty state
        print(f"No flights found for {origin} → {dest} on {data.get('date', '?')}.")
        print("Try a different date or check nearby airports.")
        return

    cheapest = flights[0]
    price = cheapest.get("price_usd", 0.0)
    duration = cheapest.get("total_duration_min", 0)
    stops = cheapest.get("stops", 0)

    print(
        f"{origin} → {dest}  ·  {len(flights)} option(s)  ·  "
        f"from ${price:.2f}  ·  {duration // 60}h {duration % 60:02d}m  ·  "
        f"{'Nonstop' if stops == 0 else f'{stops} stop(s)'}"
    )
    print("Prices may change at booking.")


if __name__ == "__main__":
    data = search_tickets("JFK", "LAX")
    display_results(data)

    try:
        search_tickets("KJFK", "KLAX")
    except ValueError as exc:
        print(f"Caught expected error: {exc}")
```

Für vorübergehende Fehler (`429`, `5xx`) verwenden Sie die Retry-Hilfsfunktion unter [Fehlerbehandlung](/docs/errors#retry-rules).

***

Siehe auch: [Flugtickets](/docs/v31/tickets) · [Flughafensuche](/docs/v31/airport-search) · [Caching & Monitoring](/docs/v31/tickets-integration-production) · [Fehlerbehandlung](/docs/errors)
