Fehlerbehandlung
Fehler treten an zwei Stellen auf, die unterschiedlich antworten:
- Bei der Anmeldung an der Token URL — der Anmeldedienst
antwortet nach dem OAuth-Standard mit den Feldern
errorunderror_description. - Beim Aufruf einer Methode — die Schnittstelle antwortet mit
einem HTTP-Statuscode und, wo möglich, einem Fehlerobjekt mit der
Meldung in
error.message.
Fehler bei der Anmeldung
Schlägt die Anforderung eines Tokens fehl, enthält die Antwort ein JSON-Objekt wie dieses:
{
"error": "invalid_request",
"error_description": "This client application is not allowed to use the specified scope.",
"error_uri": "https://documentation.openiddict.com/errors/ID2051"
}
error | error_description (Beispiel) | Ursache | Was tun? |
|---|---|---|---|
invalid_client | – | Client-ID oder Secret falsch, Client gelöscht, neues Secret noch nicht eingetragen oder Änderung noch nicht wirksam | Client-ID und Secret prüfen; nach Änderungen einige Minuten warten — siehe Speichern und Wirksamwerden |
invalid_request | This client application is not allowed to use the specified scope. (ID2051) | Ein angeforderter Scope ist dem API-Client nicht zugewiesen | Scope weglassen oder im Reiter Scopes zuweisen |
invalid_request | Die angeforderten Scopes passen nicht zur Ressource dieses Clients. | Scope einer anderen Schnittstelle angefordert, z. B. vo_… mit einem Client für die Verein-API | Nur Scopes der Ressource des Clients anfordern — siehe Scopes |
invalid_request | Parameter 'apikey' fehlt. | Beim Anmeldeweg api_key fehlt das Feld apikey | Feld apikey mitschicken — siehe Mit API-Schlüssel |
invalid_grant | API-Key ungültig. / Der API-Schlüssel ist für diesen Client nicht gültig. | API-Schlüssel falsch oder gehört zu einem anderen API-Client | API-Schlüssel im Reiter API-Benutzer erneut abrufen |
invalid_grant | Benutzer oder Passwort ungültig. | Anmeldedaten falsch | Mitglieder: E-Mail-Adresse prüfen; Vereinsbenutzer: Format <VereinsID>#<Benutzername> prüfen — siehe Mit Benutzerdaten |
unauthorized_client / unsupported_grant_type | – | Der Anmeldeweg ist für den API-Client nicht freigegeben | Passende Zugriffsart ankreuzen |
Fehler beim Aufruf einer Methode
Statuscodes
| Status | Bedeutung | Was tun? |
|---|---|---|
| 200, 204 | Erfolgreich | – |
| 400 Bad Request | Die übergebenen Daten sind ungültig, z. B. ein Pflichtfeld fehlt | error.validationErrors auswerten und die Eingabe korrigieren |
| 401 Unauthorized | Kein, ein ungültiges oder ein abgelaufenes Token — bei der MO-API auch: keine Anmeldung als Mitglied | Neues Token anfordern und den Aufruf einmal wiederholen |
| 403 Forbidden | Dem angemeldeten Benutzer fehlt ein Recht oder die Methode hat einen fachlichen Fehler gemeldet | error.message auswerten (siehe Hinweis unten) |
| 404 Not Found | Der angefragte Datensatz existiert nicht | ID prüfen |
| 500 Internal Server Error | Unerwarteter Fehler in der Schnittstelle | Später erneut versuchen; bei Wiederholung den Support mit Uhrzeit und aufgerufener Methode kontaktieren |
| 501 Not Implemented | Die Funktion ist (noch) nicht umgesetzt | – |
Fachliche Fehler — etwa ein Datensatz, der so nicht angelegt werden
kann — liefern die Schnittstellen ebenfalls mit Status 403. Werten
Sie deshalb immer error.message aus: Dort steht, ob ein Recht fehlt
oder was fachlich nicht stimmt. Die Meldung ist für Anwender
verständlich formuliert und kann direkt angezeigt werden.
Welche Statuscodes eine bestimmte Methode liefern kann, zeigt die Swagger-Oberfläche bei der Methode unter Responses.
Das Fehlerobjekt
Bei den meisten Fehlern enthält die Antwort ein JSON-Objekt mit diesem Aufbau (Beispielwerte):
{
"error": {
"code": null,
"message": "Die Anfrage konnte nicht verarbeitet werden.",
"details": null,
"data": {},
"validationErrors": null
}
}
| Feld | Bedeutung |
|---|---|
message | Die Fehlermeldung — immer auswerten |
code | Optionaler technischer Fehlercode |
details | Optionale weitere Angaben |
data | Optionale zusätzliche Daten |
validationErrors | Nur bei Status 400: Liste der ungültigen Felder, je Eintrag mit message und den betroffenen Feldnamen in members |
Bei Status 401 ist die Antwort häufig leer. Prüfen Sie deshalb immer zuerst den Statuscode und lesen Sie das Fehlerobjekt nur, wenn ein Inhalt vorhanden ist.
Fehler im Code auswerten
Das folgende Beispiel ruft die Beispielmethode der VO-API auf und wertet einen Fehler aus. Tragen Sie oben im Beispiel ein gültiges Access Token ein, z. B. aus dem Schnellstart.
- CMD
- Bash
- C#
- TypeScript
- PHP
- Python
REM ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veroeffentlichen.
REM Tragen Sie hier Ihre Werte ein:
set "ACCESS_TOKEN=access_token_aus_der_token_antwort"
REM Aufruf mit Ausgabe des HTTP-Statuscodes in der letzten Zeile;
REM bei einem Fehler steht die Meldung im Feld error.message
curl -s -w "\nHTTP-Status: %{http_code}\n" -X POST "https://voapi.netxp-verein.de/api/app/member-search/list" ^
-H "Authorization: Bearer %ACCESS_TOKEN%" ^
-H "Content-Type: application/json" ^
-d "{\"maxResultCount\": 1}"
echo.
pause
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
ACCESS_TOKEN="access_token_aus_der_token_antwort"
# Aufruf mit Ausgabe des HTTP-Statuscodes in der letzten Zeile;
# bei einem Fehler steht die Meldung im Feld error.message
curl -s -w "\nHTTP-Status: %{http_code}\n" -X POST "https://voapi.netxp-verein.de/api/app/member-search/list" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"maxResultCount": 1}'
echo
read -r -p "Mit Enter beenden ..."
using System.Net;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
var accessToken = "access_token_aus_der_token_antwort";
try
{
using var http = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://voapi.netxp-verein.de/api/app/member-search/list");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
request.Content = JsonContent.Create(new { maxResultCount = 1 });
using var response = await http.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
Console.WriteLine(body);
}
else if (response.StatusCode == HttpStatusCode.Unauthorized)
{
// Token fehlt oder ist abgelaufen: neues Token holen und den Aufruf einmal wiederholen
Console.WriteLine("401 - bitte neues Token anfordern.");
}
else
{
// Fehlerobjekt lesen; bei 403 unterscheidet error.message Rechte- und Fachfehler
var message = response.StatusCode.ToString();
if (body.Length > 0 && JsonDocument.Parse(body).RootElement.TryGetProperty("error", out var error))
{
message = error.GetProperty("message").GetString() ?? message;
}
Console.WriteLine($"{(int)response.StatusCode}: {message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Fehler: {ex.Message}");
}
Console.Write("\nMit Enter beenden ...");
Console.ReadLine();
import { createInterface } from 'node:readline/promises';
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
const accessToken = 'access_token_aus_der_token_antwort';
try {
const response = await fetch('https://voapi.netxp-verein.de/api/app/member-search/list', {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ maxResultCount: 1 }),
});
if (response.ok) {
console.log(await response.text());
} else if (response.status === 401) {
// Token fehlt oder ist abgelaufen: neues Token holen und den Aufruf einmal wiederholen
console.log('401 - bitte neues Token anfordern.');
} else {
// Fehlerobjekt lesen; bei 403 unterscheidet error.message Rechte- und Fachfehler
const body = await response.json().catch(() => null);
const message = body?.error?.message ?? response.statusText;
console.log(`${response.status}: ${message}`);
}
} catch (error) {
console.error('Fehler:', error instanceof Error ? error.message : error);
}
const rl = createInterface({ input: process.stdin, output: process.stdout });
await rl.question('\nMit Enter beenden ...');
rl.close();
<?php
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
$accessToken = 'access_token_aus_der_token_antwort';
$ch = curl_init('https://voapi.netxp-verein.de/api/app/member-search/list');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['maxResultCount' => 1]),
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $accessToken, 'Content-Type: application/json'],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($body === false) {
echo 'Verbindungsfehler: ', curl_error($ch), PHP_EOL;
} elseif ($status >= 200 && $status < 300) {
echo $body, PHP_EOL;
} elseif ($status === 401) {
// Token fehlt oder ist abgelaufen: neues Token holen und den Aufruf einmal wiederholen
echo '401 - bitte neues Token anfordern.', PHP_EOL;
} else {
// Fehlerobjekt lesen; bei 403 unterscheidet error.message Rechte- und Fachfehler
$error = json_decode((string) $body, true);
$message = $error['error']['message'] ?? 'unbekannter Fehler';
echo $status, ': ', $message, PHP_EOL;
}
echo PHP_EOL, 'Mit Enter beenden ...';
fgets(STDIN);
import requests
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
ACCESS_TOKEN = "access_token_aus_der_token_antwort"
try:
response = requests.post(
"https://voapi.netxp-verein.de/api/app/member-search/list",
headers={"Authorization": f"Bearer {ACCESS_TOKEN}"},
json={"maxResultCount": 1},
timeout=30,
)
except requests.RequestException as error:
print(f"Verbindungsfehler: {error}")
else:
if response.ok:
print(response.text)
elif response.status_code == 401:
# Token fehlt oder ist abgelaufen: neues Token holen und den Aufruf einmal wiederholen
print("401 - bitte neues Token anfordern.")
else:
# Fehlerobjekt lesen; bei 403 unterscheidet error.message Rechte- und Fachfehler
try:
error = response.json().get("error") or {}
except ValueError:
error = {}
message = error.get("message") or response.reason
print(f"{response.status_code}: {message}")
input("\nMit Enter beenden ...")
Fehler beim Einrichten
Probleme beim Anlegen und Speichern eines API-Clients sind auf der Seite API-Clients unter Häufige Fehler beschrieben.
Verwandte Themen
- Authentifizierung — Anmeldewege und Tokens
- Schnellstart — vollständige Beispiele je Schnittstelle
- Übersicht — Verbindungsdaten und Swagger-Oberfläche
- API-Clients — Einrichtung des API-Clients