Fehlerbehandlung

Dieses Kapitel erklärt HTTP-Status-Codes und wie du Fehler korrekt behandelst.

HTTP-Status-Codes

Erfolgreiche Antworten (2xx)

CodeNameBedeutungVerwendung
200OKAnfrage erfolgreichGET, PUT, PATCH
201CreatedObjekt erstelltPOST
204No ContentGelöscht (keine Daten)DELETE

Client-Fehler (4xx)

CodeNameBedeutung
400Bad RequestUngültige Anfrage/Validierungsfehler
401UnauthorizedAuthentifizierung erforderlich/fehlgeschlagen
403ForbiddenKeine Berechtigung
404Not FoundObjekt nicht gefunden
405Method Not AllowedHTTP-Methode nicht erlaubt
409ConflictKonflikt (z.B. Duplikat)

Server-Fehler (5xx)

CodeNameBedeutung
500Internal Server ErrorServer-Fehler
502Bad GatewayUpstream-Server-Problem
503Service UnavailableService überlastet

Fehler-Response-Format

Validierungsfehler (400)

{
  "email": ["Gültige E-Mail-Adresse erforderlich."],
  "vorname": ["Dieses Feld darf nicht leer sein."],
  "start_date": ["Datum hat falsches Format."]
}

Felder mit Fehlern werden als Keys aufgelistet, Fehlermeldungen als Array.

Authentifizierungsfehler (401)

{
  "detail": "Authentication credentials were not provided."
}

Oder bei ungültigem Token:

{
  "detail": "Invalid token."
}

Berechtigungsfehler (403)

{
  "detail": "You do not have permission to perform this action."
}

Nicht gefunden (404)

{
  "detail": "Not found."
}

Fehlerbehandlung in Python

Einfache Prüfung

response = session.get(f"{BASE_URL}/organisation/mitarbeitende/999")

if response.status_code == 200:
    mitarbeiter = response.json()
elif response.status_code == 404:
    print("Mitarbeiter nicht gefunden")
elif response.status_code == 401:
    print("Authentifizierung fehlgeschlagen")
else:
    print(f"Unerwarteter Fehler: {response.status_code}")

Mit Exception-Handling

try:
    response = session.get(f"{BASE_URL}/organisation/mitarbeitende/999")
    response.raise_for_status()  # Wirft Exception bei 4xx/5xx
    mitarbeiter = response.json()

except requests.exceptions.HTTPError as e:
    if e.response.status_code == 404:
        print("Nicht gefunden")
    elif e.response.status_code == 401:
        print("Bitte Token prüfen")
    else:
        print(f"HTTP-Fehler: {e}")

except requests.exceptions.ConnectionError:
    print("Verbindung zum Server fehlgeschlagen")

except requests.exceptions.Timeout:
    print("Timeout - Server antwortet nicht")

Validierungsfehler auswerten

response = session.post(
    f"{BASE_URL}/organisation/mitarbeitende",
    json={"vorname": "", "email": "ungültig"}
)

if response.status_code == 400:
    fehler = response.json()

    for feld, meldungen in fehler.items():
        for meldung in meldungen:
            print(f"Feld '{feld}': {meldung}")

Ausgabe:

Feld 'vorname': Dieses Feld darf nicht leer sein.
Feld 'email': Gültige E-Mail-Adresse erforderlich.

Häufige Fehler und Lösungen

401 Unauthorized

Problem: Token fehlt oder ist ungültig

Lösungen:

# 1. Header prüfen
print(session.headers)  # Authorization vorhanden?

# 2. Token-Format prüfen (mit Leerzeichen nach "Token")
session.headers["Authorization"] = f"Token {API_TOKEN}"  # Richtig
session.headers["Authorization"] = f"Token{API_TOKEN}"   # Falsch!

# 3. Token in ELIZA prüfen - noch gültig?

403 Forbidden

Problem: Keine Berechtigung für diese Aktion

Lösungen:

  • Prüfe, ob dein Benutzer die nötigen Rechte hat
  • Kontaktiere den ELIZA-Administrator
  • Prüfe, ob du die richtige HTTP-Methode verwendest

404 Not Found

Problem: Objekt existiert nicht

Lösungen:

# 1. ID prüfen
response = session.get(f"{BASE_URL}/organisation/mitarbeitende/123")

# 2. Objekt suchen statt direkt zugreifen
response = session.get(f"{BASE_URL}/organisation/mitarbeitende?search=hugo")
if response.json():
    mitarbeiter = response.json()[0]

400 Bad Request

Problem: Ungültige Daten gesendet

Lösungen:

# Fehlermeldungen auslesen
if response.status_code == 400:
    print("Validierungsfehler:")
    for feld, fehler in response.json().items():
        print(f"  {feld}: {', '.join(fehler)}")

500 Internal Server Error

Problem: Server-seitiger Fehler

Lösungen:

  • Warte einen Moment und versuche es erneut
  • Prüfe die Anfrage auf ungewöhnliche Daten
  • Kontaktiere den Support mit Request-Details

Retry-Logik

Für robuste Integrationen:

import time
from requests.exceptions import RequestException

def api_request_mit_retry(methode, url, max_versuche=3, **kwargs):
    """API-Anfrage mit automatischem Retry bei Fehlern."""

    for versuch in range(max_versuche):
        try:
            response = methode(url, **kwargs)

            # Bei Server-Fehlern retry
            if response.status_code >= 500:
                if versuch < max_versuche - 1:
                    time.sleep(2 ** versuch)  # Exponential backoff
                    continue

            return response

        except RequestException as e:
            if versuch < max_versuche - 1:
                time.sleep(2 ** versuch)
                continue
            raise

    return response

# Verwendung
response = api_request_mit_retry(
    session.get,
    f"{BASE_URL}/organisation/mitarbeitende"
)

Logging für Debugging

import logging

logging.basicConfig(level=logging.DEBUG)

# Requests-Logging aktivieren
logging.getLogger("urllib3").setLevel(logging.DEBUG)

# Eigenes Logging
logger = logging.getLogger(__name__)

response = session.get(url)
logger.info(f"GET {url} -> {response.status_code}")

if response.status_code >= 400:
    logger.error(f"Fehler-Response: {response.text}")

Nächste Schritte

Praxisbeispiele - Vollständige Integrationen

Best Practices - Produktionsreife Implementierung


Zusammenfassung

✅ 2xx = Erfolg, 4xx = Client-Fehler, 5xx = Server-Fehler

✅ Validierungsfehler liefern feldspezifische Meldungen

raise_for_status() für Exception bei Fehlern

✅ Retry-Logik für robuste Integrationen

✅ Logging für Debugging aktivieren

api fehler http-status debugging