Fehler
Jeder Fehlschlag kommt in einem Umschlag zurück, gleich welche Route ihn abgelehnt hat:
{
"error": {
"type": "https://reelwire.io/errors/forbidden",
"code": "forbidden",
"message": "This key may not read here. Give it the \"Team: read\" permission, or use a key that has it.",
"requestId": "01M2SR17R25EKN6DM1H9DVDS0D",
"details": []
}
}
Die Felder und wofür jedes da ist:
| Feld | Was es ist |
|---|---|
code | Der maschinenlesbare Grund. Verzweigen Sie danach, nie nach der Meldung. |
type | Ein stabiler Dokumentations-URI, https://reelwire.io/errors/{code}. Er trägt keine Informationen über den Code hinaus. |
message | Für Menschen geschrieben und sicher in Ihrer eigenen Oberfläche anzeigbar. Er enthält nie einen Stacktrace oder ein Geheimnis. |
requestId | Eine ULID, die diesen Fehlschlag mit der Logzeile in jedem Container verknüpft, den die Anfrage berührt hat. Derselbe Wert steht im Antwort-Header x-request-id jeder Antwort, ob erfolgreich oder nicht. Senden Sie eine eigene ULID in diesem Header, wird sie stattdessen verwendet; alles, was keine ULID ist, wird durch eine neue ersetzt. |
details | Ein Eintrag je Problem, jeweils mit einem JSON Pointer in den Anfragetext. |
retryAfterSeconds | Vorhanden, wenn Warten die Lösung ist: bei einem Ratenlimit, mit derselben Zahl in einem Header Retry-After. |
Nennen Sie die requestId, wenn Sie nach einem Fehlschlag fragen. Sie ist der eine Wert, der die Anfrage wiederfindet.
Die Seiten, die eine Person im Browser öffnet, statt sie aufzurufen, sind die Ausnahme, weil ein Mensch sie liest: das Beitragspaket, die Seite einer Syndikationsgruppe und die Seiten, die ihre E-Mails öffnen, antworten mit einer eigenen Seite, etwa 410 Gone für einen Link nach Ablauf seiner Zeit.
Details tragen einen Pointer je Problem
details macht eine Ablehnung handlungsfähig: Ein Client kann auf das genaue Feld zeigen, statt einen Absatz auszugeben und jemanden suchen zu lassen.
curl http://localhost:4000/v1/stream \
-H "Authorization: Bearer rw_your_key_here" \
-H "Content-Type: application/json" \
-d '{"streamId":"st_30472168d941","eventId":"not-a-ulid","occurredAt":"yesterday","data":{}}'
{
"error": {
"type": "https://reelwire.io/errors/schema_validation",
"code": "schema_validation",
"message": "Stream envelope is not valid",
"requestId": "01M2SQNH1MDKPWQ83Y3ECG60M3",
"details": [
{ "path": "/eventId", "message": "must be a Crockford base32 ULID", "rule": "invalid_string" },
{ "path": "/occurredAt", "message": "Invalid datetime", "rule": "invalid_string" }
]
}
}
path ist ein JSON Pointer nach RFC 6901 in den Text, den Sie gesendet haben. Ein leerer String bedeutet das Dokument als Ganzes. rule ist ein optionaler maschinenlesbarer Hinweis, und expected und received erscheinen, wo der Prüfer beide kannte.
Die Codes und der Status, den jeder trägt
Eine Route wählt nie ihren eigenen Status: Der Code entscheidet ihn, in einer Tabelle. Die Tabelle gilt für jede Grenze von Reelwire, daher gehören einige Codes, etwa replayed und timestamp_skew, zu signierten Zustellungen und nicht zu etwas, das Sie aufrufen.
| Code | Status | Wann |
|---|---|---|
malformed_json | 400 | Der Text ist kein JSON. |
schema_validation | 400 | Wohlgeformtes JSON, das nicht zur Form passt. |
ratio_not_supported | 400 | Die Vorlage kommt nicht in dieser Form. |
locale_not_supported | 400 | In dieser Sprache wird nichts gerendert. |
blocked_url | 400 | Eine URL, die Reelwire nicht abruft oder an die es nicht zustellt. |
unauthenticated | 401 | Fehlende oder ungültige Zugangsdaten, oder das Token eines KI-Assistenten, das direkt an die API statt über den MCP-Server von Reelwire gesendet wurde. |
signature_invalid | 401 | Eine Signatur, die nicht stimmt. |
timestamp_skew | 401 | Eine signierte Anfrage, die zu weit von jetzt entfernt ist. |
forbidden | 403 | Gültige Zugangsdaten, die dies nicht tun dürfen, oder ein falsches Passwort, wo eine Route es erneut verlangt, etwa beim Anzeigen eines Schlüssels. |
not_found | 404 | So etwas gibt es nicht, oder es gehört nicht Ihnen. |
unknown_source | 404 | Kein mitgelieferter Feed unter diesem Source-Slug. |
unknown_format | 404 | Kein solches Format unter dieser Quelle. |
unknown_template | 404 | Keine solche Vorlage. |
unknown_stream | 404 | Kein Stream mit dieser ID in diesem Konto. |
conflict | 409 | Ein Konflikt mit dem, was schon da ist. |
idempotency_conflict | 409 | Dieselbe eventId mit einem anderen Text. |
invalid_state_transition | 409 | Die Sache ist nicht in einem Zustand, auf den diese Aktion zutrifft. |
stream_disabled | 409 | Der Stream existiert und ist ausgeschaltet. |
no_sample | 409 | Nach den eigenen Feldnamen eines Streams gefragt, bevor er etwas empfangen hat. |
template_not_approved | 409 | Die Vorlage ist für diesen Workspace nicht freigegeben. |
replayed | 409 | Eine Zustell-ID, die schon verarbeitet wurde. |
payload_too_large | 413 | Über dem Größenlimit dieser Route. |
unsupported_media_type | 415 | Der falsche Content-Type, etwa JSON, das an eine Route gesendet wurde, die eine Datei nimmt. |
rate_limited | 429 | Zu viele Anfragen. retryAfterSeconds sagt, wie lange zu warten ist. Auch ein aufgebrauchtes Kontingent: keine Videos mehr in diesem Monat oder kein Platz mehr im Medienanteil des Speichers der Mediathek. Dieses trägt kein retryAfterSeconds, weil Warten es nicht behebt. |
internal | 500 | Ein Fehler auf der Seite von Reelwire. |
render_failed | 502 | Der Renderer hat den Auftrag abgelehnt. |
asset_unavailable | 502 | Eine Datei, die das Rendern brauchte, konnte nicht abgerufen werden, oder ein Video wurde angefordert, bevor es fertig war. |
checksum_mismatch | 502 | Eine Datei ist angekommen, ist aber nicht die versprochene. |
upstream_unavailable | 503 | Eine Abhängigkeit ist ausgefallen, etwa wenn jeder Renderer unerreichbar ist. |
render_timeout | 504 | Der Renderer hat zu lange gebraucht. |
Zwei Ergebnisse, die nach Fehlschlägen klingen, sind es absichtlich nicht. Ein Ereignis, das älter ist, als sein Feed annimmt, wird mit 202 und status: "stale" in einer gewöhnlichen Antwort beantwortet, nicht in einem Fehlerumschlag: Es war wohlgeformt und wurde gespeichert, und nichts wurde gerendert. Ein Produzent, der Historie wiedergibt, sieht Erfolg statt einer Wand von 4xx, die einen echten Fehler darin verbergen würde. Der Code stale_event trägt aus demselben Grund 202 in der Tabelle. Siehe Ereignisse senden.
Das andere ist eine Änderung dessen, was ein Workspace zahlt, wenn die Bank der Karte will, dass der Karteninhaber die Zahlung bestätigt: 202 mit { "confirmation": { "url": "...", "label": "...", "expiresAt": "..." } }, der Seite, auf der er sie bestätigt. Sie wurde angenommen und ist noch nicht erledigt. Diese Routen sind für eine angemeldete Person, sodass nur ein Client, der für eine handelt, ihr begegnet.
404 und 403 sind nicht austauschbar
Etwas, das zu einem anderen Workspace gehört, antwortet genau wie etwas, das nicht existiert. Das ist Absicht: Einem Fremden zu sagen, dass st_000000000000 existiert, aber nicht ihm gehört, heißt, ihm etwas zu sagen. Ein 403 bedeutet, dass die Zugangsdaten Ihre sind und die Aktion nicht erlaubt ist, und die Meldung nennt die Berechtigung, die hinzuzufügen ist. Siehe Berechtigungen.
Wiederholen
429 und 503 lohnt es sich zu wiederholen, nach retryAfterSeconds, wo es angegeben ist, und sonst mit einem Backoff. Die Limits selbst stehen unter Ratenlimits. Ein 429 ohne retryAfterSeconds ist die Ausnahme: Es ist ein aufgebrauchtes Kontingent und antwortet gleich, bis der Monat zurückgesetzt wird, mehr gekauft wird oder Dateien gelöscht werden, um Platz zu schaffen; seine Meldung sagt, was zutrifft. 502 und 504 bei einem Render lohnt sich ein Wiederholen einmal. Alles andere im 4xx-Bereich nicht: Die Anfrage wird gleich abgelehnt, bis sie sich ändert.
Sendungen tragen eine eventId, die einen Wiederholungsversuch idempotent macht, sodass das Wiederholen nach einem Timeout nicht zweimal veröffentlichen kann. Siehe Ereignisse senden.