Fehlerbehandlung
Die öffentliche API nutzt standardmäßige HTTP-Statuscodes und JSON-Bodies. Clients sollten „Anfrage fehlgeschlagen", „erfolgreich, aber noch keine Daten" und „Knoten offline" unterscheiden.
Statuscodes
| Status | Bedeutung | Client-Verhalten |
|---|---|---|
200 | Erfolg | JSON parsen; null, leere Arrays und neue Felder akzeptieren |
204 | CORS-Preflight erfolgreich | kein Body |
400 | Parameter fehlt oder ungültig | Anfrage korrigieren, nicht unverändert wiederholen |
401 | Token/Session ungültig | nur geschützte Endpoints; Zugangsdaten nie loggen |
403 | Origin, Berechtigung oder Policy abgelehnt | exakte Origin und Umfang prüfen |
404 | Ressource oder Ziel fehlt | ID, aktivierten Zustand, Deployment-Version prüfen |
409 | Zustandskonflikt mit Vorbedingung | Admin-Daten aktualisieren und neu bestätigen |
413 | Body oder Upload zu groß | Anfrage oder ZIP verkleinern |
415 | nicht unterstützter Content-Type | erlaubten ZIP-Content-Type verwenden |
429 | Rate-Limit erreicht | Retry-After beachten, exponentiell zurückweichen |
500–504 | transitorischer Server-/Upstream-Fehler | begrenzt oft mit Jitter wiederholen |
Retry-Strategie
Wiederholen Sie nur idempotente GET-Anfragen, mit Limit:
async function getJson(url, attempts = 3) {
for (let attempt = 0; attempt < attempts; attempt += 1) {
const response = await fetch(url, { credentials: 'omit' })
if (response.ok) return response.json()
if (![429, 500, 502, 503, 504].includes(response.status)) {
throw new Error(`Request rejected: HTTP ${response.status}`)
}
const retryAfter = Number(response.headers.get('retry-after') || 0) * 1000
const backoff = Math.max(retryAfter, 500 * (2 ** attempt))
const jitter = Math.floor(Math.random() * 250)
await new Promise(resolve => setTimeout(resolve, backoff + jitter))
}
throw new Error('API temporarily unavailable')
}Leere Daten sind kein Fehler
All das ist normal:
- Ein neuer Agent hat noch nicht gemeldet:
latestistnull. - Keine Pings im Fenster:
pingsist leer. - Externe Latenzquellen haben das Frischefenster überschritten:
sourcesist leer. - Das Ziel verbirgt seine öffentliche Adresse: Cloudflare und externe Latenz werden nicht angezeigt.
- Sensoren in Virtualisierung nicht verfügbar: Temperatur ist
null.
Zeigen Sie „noch keine Daten" statt eine Exception zu werfen. warnings[] bedeutet, dass der Haupt-Payload kam, aber eine optionale Quelle fehlschlug; Inhalt behalten und einen nicht blockierenden Hinweis anzeigen. Umgekehrt garantiert HTTP 200 keinen Erfolg: Der Latency-Kompatibilitätspfad kann { "ok": false, "error": "..." } liefern, also prüfen Sie Status und ok.
Kompatibilitätsregeln
v1 darf optionale Felder hinzufügen, aber vorhandene Felder nie stillschweigend löschen oder umbenennen. Clients sollten: api_version prüfen; unbekannte Felder ignorieren; sich nicht auf die JSON-Schlüsselreihenfolge verlassen; Zeitstempel explizit sortieren; Defaults für null, fehlende Felder und leere Arrays definieren; Fehlertext nie per innerHTML injizieren.
Browser-CORS-Fehler
Wenn curl funktioniert, aber der Browser nicht, fehlt die Origin in DEVELOPER_API_ORIGINS. Die Allowlist braucht vollständige Origins wie https://status.example.com, ohne Pfad und ohne *. HTTP ist nur für die Dev-Adressen localhost, 127.0.0.1 und [::1] erlaubt.
429 bei der Update-Prüfung
Wenn die Update-Karte beim Lesen des offiziellen Manifests 429 erhält, fällt sie auf einen Cache oder das gebündelte Manifest zurück und markiert die Quelle. Behandeln Sie den degradierten Zustand nicht als Agent-Update-Fehler und hämmern Sie nicht auf Refresh, um das 15-Minuten-Backoff zu umgehen. Nur wenn offizielles, Cache- und gebündeltes Manifest alle nicht verfügbar sind, gilt es als transitorischer Serverfehler.
Diagnose sicher sammeln
Protokollieren: App-/Agent-Version, Zeitstempel, Methode und Pfad, HTTP-Status, X-NIE-SLA-API-Version, X-NIE-SLA-Cache (oder v1-Aliasse) sowie bereinigte error/warnings. Nie protokollieren: Authorization, x-admin-session, TOTP, vollständige Agent-Installationsbefehle, Backup-Passwörter oder NQ-Image-Host-URLs/-Tokens.