Fehler und Wiederholungen: die Referenz
Ein Fehlerumschlag auf jedem Endpunkt: jeder Code mit HTTP-Status und retryable-Flag, wie die SDKs zurückweichen und was 410 und 426 bedeuten.
Zuletzt aktualisiert:
Kann eine Anfrage nicht bedient werden, antwortet jeder Endpunkt gleich — ein Umschlag, maschinenlesbar, mit genug Inhalt für die nächste Entscheidung. Die Beispiele unten authentifizieren sich wie alles andere hier: ein bb_-API-Schlüssel als Bearer-Token.
Der Umschlag
Jedes Scheitern ist error mit code, message, retryable und optional retryAfterMs, requestId und details. Verzweige auf retryable, nie auf den Code: Das Code-Enum ist offen, und ein neuerer Server kann Codes einführen, die dein switch nicht kennt. requestId ist, wonach der Support fragt; details trägt strukturierte Einzelheiten, etwa die vollständige Validierungsfehlerliste eines Workflows.
Wie die SDKs wiederholen
Beide SDKs respektieren retryAfterMs und weichen mit vollem Jitter zurück, wenn es fehlt. Eine bewusste Ausnahme: Das TypeScript-SDK wiederholt keinen POST, der auf Verbindungsebene scheiterte, denn ein Create, dessen Antwort unterwegs verloren ging, kann serverseitig gelungen sein — blindes Wiederholen machte aus einer gewünschten Session zwei.
Jeder Code
Das aktuelle Vokabular — und es bleibt offen.
| Name | Typ | Beschreibung |
|---|---|---|
unauthorized
|
HTTP 401 | Kein Schlüssel oder ein nicht existierender. Nicht wiederholbar. |
forbidden
|
HTTP 403 | Der Schlüssel ist gültig, darf das aber nicht. Nicht wiederholbar. |
not_found
|
HTTP 404 | Die Ressource existiert für diese Organisation nicht. Nicht wiederholbar. |
invalid_request
|
HTTP 400 | Der Body scheiterte an der Validierung — Requests sind strikt, ein vertipptes Feld landet also hier. Nicht wiederholbar. |
disallowed_browser_arg
|
HTTP 400 | Ein `extraArgs`-Eintrag liegt außerhalb der Allowlist. Nicht wiederholbar. |
conflict
|
HTTP 409 | Die Anfrage widerspricht dem aktuellen Zustand. Nicht wiederholbar. |
rate_limited
|
HTTP 429 | Zu viele Anfragen. Wiederholbar, meist mit `retryAfterMs`. |
quota_exceeded
|
HTTP 402 | Ein Tarifkontingent ist erschöpft. Nicht wiederholbar — die Lösung ist der Tarif, keine Wiederholung. |
concurrency_limit
|
HTTP 429 | Zu viel läuft gleichzeitig für die Organisation. Wiederholbar, sobald etwas endet. |
queue_timeout
|
HTTP 429 | Die Anfrage wartete zu lange in der Warteschlange. Wiederholbar. |
capacity_unavailable
|
HTTP 503 | Gerade keine Kapazität — oder, selbst gehostet, ein fehlender Schlüssel-Provider. Wiederholbar. |
session_expired
|
HTTP 410 | Die Session erreichte ihre Frist. Nicht wiederholbar — lege eine neue Session an. |
session_gone
|
HTTP 410 | Die Session wurde freigegeben oder ihr Container ist weg. Nicht wiederholbar. |
launch_failed
|
HTTP 502 | Der Browser-Container startete nicht. Wiederholbar. |
protocol_incompatible
|
HTTP 426 | Client und Server können keine Protokollversion aushandeln. Nicht wiederholbar. |
navigation_failed
|
422 | Die Task-API konnte `startUrl` vor dem Start des Laufs nicht öffnen. So nicht wiederholbar: URL korrigieren, oder die Site verweigert. |
internal
|
HTTP 500 | Etwas ging auf unserer Seite schief. Wiederholbar. |
426 und die zwei 410er
protocol_incompatible heißt meist: Dein Client spricht ein neueres Minor als der Server — die Aushandlung verlangt exakt gleiche Majors und ein Server-Minor mindestens auf deiner Höhe, also aktualisiere den Server oder pinne einen älteren Client; Wiederholen ändert nichts. Die beiden 410er unterscheiden sich in ihrer Geschichte: session_expired sagt, die Session traf eine Frist, die sie immer treffen würde; session_gone sagt, sie wurde freigegeben oder ihr Container existiert nicht mehr. Beide enden gleich — neue Session —, aber das erste ist ein Planungssignal, und das zweite verdient womöglich einen Blick auf shutdownReason.
Den Umschlag sehen
Ein GET auf eine nicht existierende Session zeigt den Umschlag genau so, wie ihn jedes andere Scheitern zurückgibt.
Voraussetzungen: api-key
# Two refusals, one envelope shape. not_found is terminal; retryable says so.
curl -s "https://browserberg.com/v1/sessions/sess_does_not_exist" \
-H "Authorization: Bearer $BROWSERBERG_API_KEY" \
| python3 -m json.tool
{
"error": {
"code": "not_found",
"message": "No such session.",
"retryable": false,
"requestId": "req_xxxxxxxx"
}
}