> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# GraphQL-Fehler

> Wie die Ayrshare-GraphQL-API Fehler meldet, von HTTP-Statuscodes bei fehlerhaften Anfragen bis hin zum errors-Array, Teilerfolgen, idempotenten Wiederholungen und Rate-Limits.

<h2 id="resolver-errors-arrive-with-http-200">
  Resolver-Fehler kommen mit HTTP 200 an
</h2>

Das ist das Wichtigste, was Sie wissen sollten, bevor Sie Ihre Fehlerbehandlung schreiben.

Gemäß der Spezifikation für GraphQL over HTTP gibt eine Anfrage, die unsere Resolver erreicht, **HTTP 200 zurück, selbst wenn eine Operation fehlgeschlagen ist**. Der Fehler wird im Antwort-Body gemeldet, nicht über den Statuscode.

Diese Prüfung funktioniert daher nicht:

```javascript theme={"system"}
// FALSCH - behandelt eine fehlgeschlagene Anfrage als Erfolg
if (response.ok) {
  return "everything worked";
}
```

Prüfen Sie stattdessen den Body. Einige Transportfehler, etwa 415 bei einem nicht unterstützten `Content-Type`, haben einen leeren Body. Prüfen Sie daher vor dem Parsen, ob die Antwort JSON ist:

```javascript theme={"system"}
if (!response.headers.get("content-type")?.includes("json")) {
  throw new Error(`GraphQL request failed with HTTP ${response.status}`);
}

const result = await response.json();

if (result.errors) {
  for (const error of result.errors) {
    // Vor der Ausführung abgefangene Fehler haben keine extensions, daher sicher lesen.
    console.log(error.message, error.extensions?.status);
  }
}
```

Manche Fehler werden abgefangen, bevor überhaupt etwas ausgeführt wird. Keiner davon erreicht einen Resolver oder verbraucht einen API-Aufruf:

<ul class="custom-bullets">
  <li>Eine fehlerhafte Anfrage gibt einen Fehlerstatus zurück: <strong>HTTP 400</strong> bei ungültigem JSON oder fehlender <code>query</code>, <strong>413</strong> bei einem Body über 64 KB, <strong>405</strong> bei einer anderen Methode als <code>POST</code> und <strong>415</strong> bei einem nicht unterstützten <code>Content-Type</code>.</li>
  <li>Eine Query, die für das Schema nicht gültig ist, gibt nur dann <strong>HTTP 400</strong> zurück, wenn Ihre Anfrage <code>Accept: application/graphql-response+json</code> sendet. Das betrifft Syntaxfehler, unbekannte Felder, falsche Argumenttypen, ungültige Enum-Werte und Queries, die die <a href="/docs/apis/graphql/limits#query-limits">Abfragelimits</a> überschreiten. Wenn Sie <code>Accept: application/json</code> oder keinen <code>Accept</code>-Header senden, gibt derselbe Fehler <strong>HTTP 200</strong> zurück. In beiden Fällen enthält der Body ein <code>errors</code>-Array und kein <code>data</code>.</li>
</ul>

Sobald die Ausführung beginnt, geben Eingabevalidierungen auf Resolver-Ebene und API-Fehler – einschließlich Authentifizierung, Autorisierung, Upstream-Rate-Limits und Upstream-5xx-Antworten – HTTP 200 mit einem `errors`-Array zurück.

<h2 id="the-error-shape">
  Die Fehlerstruktur
</h2>

Jeder Resolver-Fehler enthält seinen HTTP-ähnlichen API-Status in `extensions`:

```json theme={"system"}
{
  "data": { "postHistory": null },
  "errors": [
    {
      "message": "Rate limit exceeded",
      "path": ["postHistory"],
      "extensions": {
        "status": 429,
        "retryAfter": 7
      }
    }
  ]
}
```

<ul class="custom-bullets">
  <li><code>message</code> – eine lesbare Beschreibung. Wir entfernen API Keys und andere Zugangsdaten aus Resolver-Fehlermeldungen, aber ein Fehler zu einem von Ihnen gesendeten Wert, etwa einer Variablen mit falschem Typ, kann diesen Wert wiederholen. Behandeln Sie <code>message</code> als potenziell sensibel, bevor Sie sie protokollieren.</li>
  <li><code>path</code> – welches Feld in Ihrer Query fehlgeschlagen ist. Bei mehreren Feldern in einer Anfrage erkennen Sie daran, welches betroffen ist.</li>
  <li><code>extensions.status</code> – der HTTP-Status, den der entsprechende REST-Aufruf zurückgegeben hätte. Verzweigen Sie anhand dieses Werts.</li>
  <li><code>extensions.code</code> – der numerische Ayrshare-Fehlercode, sofern der zugrunde liegende Endpunkt einen liefert.</li>
  <li><code>extensions.retryAfter</code> – vorhanden bei Upstream-429-Fehlern wegen Kontingent oder Rate-Limit, wenn eine Wartezeit für die Wiederholung verfügbar ist. Beim 429 des Dispatch-Budgets pro Anfrage ist es nicht vorhanden.</li>
</ul>

Verwenden Sie `extensions.code` mit der [Referenz der Fehlercodes](/docs/errors/overview) oder übergeben Sie ihn an `explainError`.

<h2 id="partial-success">
  Teilerfolg
</h2>

Wenn eine Anfrage nach mehreren Dingen fragt und nur einige davon erfolgreich sind, erhalten Sie **sowohl** `data` als auch `errors`:

```graphql theme={"system"}
{
  history: postHistory(lastDays: 7)
  analytics: socialAnalytics(platforms: [INSTAGRAM])
}
```

```json theme={"system"}
{
  "data": {
    "history": { "history": [{ "id": "RkQ8uXg2jT7bNd1Wq0Ya", "status": "success", "post": "Hello world" }], "refId": "9d2a7c41f0b8e6d35a1c", "count": 1, "lastUpdated": "2026-09-24T12:00:00.000Z", "nextUpdate": "2026-09-24T12:00:00.000Z" },
    "analytics": null
  },
  "errors": [
    {
      "message": "Rate limit exceeded",
      "path": ["analytics"],
      "extensions": { "status": 429 }
    }
  ]
}
```

`history` war erfolgreich, und seine Daten sind verwendbar. Nur `analytics` muss wiederholt werden. Verwerfen Sie nicht die gesamte Antwort, nur weil `errors` vorhanden ist – damit würden Sie Daten wegwerfen, die Ihnen bereits berechnet wurden.

<h2 id="partial-success-on-multi-network-posts">
  Teilerfolg bei Beiträgen in mehreren Netzwerken
</h2>

Ein Beitrag in mehreren Netzwerken kann in einigen erfolgreich sein und in anderen fehlschlagen. Das wird **nicht** als GraphQL-Fehler gemeldet, weil die Operation selbst funktioniert hat – sie hat genau das getan, was Sie angefordert haben, und teilt Ihnen mit, was passiert ist.

Das Ergebnis trennt die drei möglichen Ausgänge:

```graphql theme={"system"}
mutation {
  createPost(input: {
    post: "Hi"
    platforms: [FACEBOOK, INSTAGRAM]
    idempotencyKey: "multi-network-hi-001"
  }) {
    status
    postIds { platform postUrl }
    errors { platform message code }
    blocked { platform message }
  }
}
```

<ul class="custom-bullets">
  <li><code>postIds</code> – Netzwerke, in denen veröffentlicht wurde, mit ihren Beitrags-URLs. Nur Erfolge.</li>
  <li><code>errors</code> – Netzwerke, in denen es fehlgeschlagen ist, mit dem Grund.</li>
  <li><code>blocked</code> – Netzwerke, die vor einem Versuch gestoppt wurden, zum Beispiel durch den netzwerkspezifischen Circuit Breaker nach wiederholten deterministischen Fehlern. Diese sind getrennt von Anbieterversuchen, die Fehler zurückgegeben haben.</li>
</ul>

`status` ist `"error"`, wenn **irgendein** Netzwerk fehlgeschlagen ist. Es ist also kein verlässliches Signal dafür, dass nichts veröffentlicht wurde. Lesen Sie `postIds`, um herauszufinden, was veröffentlicht wurde.

<h2 id="retries">
  Wiederholungen
</h2>

**Die GraphQL-API wiederholt niemals automatisch.** Wenn eine Anfrage fehlschlägt, wurde in Ihrem Namen nichts unbemerkt erneut versucht.

Das ist vor allem bei Mutations wichtig. `createPost` stellt `idempotencyKey` bereit: Erzeugen Sie vor dem ersten Versuch einen eindeutigen Schlüssel und verwenden Sie dann denselben Schlüssel und dieselbe Nutzlast für jede Wiederholung. Eine abgeschlossene Wiederholung liefert das ursprüngliche Ergebnis erneut, statt den Schreibvorgang zu wiederholen. Wechseln Sie nach einer uneindeutigen Antwort nicht zu einem neuen Schlüssel.

`boostFacebookPost` und `instagramBoostPost` nehmen ebenfalls einen `idempotencyKey` entgegen, und er schützt echtes Geld. Eine Wiederholung mit demselben Schlüssel und denselben Argumenten gibt das ursprüngliche Ergebnis zurück, markiert mit `idempotentReplayed: true`, statt eine zweite Anzeige zu erstellen und zu bezahlen. Ein Schlüssel gilt für Ihr gesamtes Konto auf beiden Meta-Plattformen. Verwenden Sie den Schlüssel eines Facebook-Boosts daher niemals für einen Instagram-Boost.

Wenn ein Schlüssel abgelehnt wird, verrät Ihnen `extensions.status` den Grund. `createPost` gibt 409 zurück, solange der erste Versuch noch verarbeitet wird – warten Sie dann und wiederholen Sie mit demselben Schlüssel –, und 400, wenn sich die Nutzlast vom ersten Versuch unterscheidet. Die Boost-Mutations geben in beiden Fällen 409 zurück, und ebenso, wenn der Schlüssel für einen Boost auf der anderen Plattform verwendet wurde.

Andere Schreibvorgänge, etwa `addComment`, haben keinen Idempotenzschlüssel. Wenn ihre Antwort verloren geht, prüfen Sie den Zustand im sozialen Netzwerk oder in der API, bevor Sie entscheiden, ob ein weiterer Versuch sicher ist.

Zwei verschiedene Limits melden beide 429 und erfordern eine unterschiedliche Behandlung. Das Dispatch-Budget lehnt Root-Felder erst ab, wenn in derselben Anfrage bereits fünf API-Aufrufe gestartet wurden, und seine Meldung beginnt mit `Query exceeds the per-request dispatch budget`: Teilen Sie diese Felder auf Anfragen mit höchstens fünf Feldern auf, ohne warten zu müssen. Jeder andere 429 ist ein Rate-Limit oder Kontingent: Warten Sie `extensions.retryAfter` Sekunden, wenn der Wert vorhanden ist, andernfalls warten Sie vor der Wiederholung schrittweise länger, und wiederholen Sie nur die fehlgeschlagenen Felder. Bei einem 5xx bei einem **Lesevorgang** ist eine Wiederholung sicher, mit einer Ausnahme: `generatePost` ist eine Query, aber eine Wiederholung ruft den KI-Generator erneut auf, zählt als weiterer API-Aufruf und gibt einen anderen Text zurück. Bei einem 5xx bei einem Schreibvorgang ohne Idempotenz prüfen Sie vor der Wiederholung, ob er wirksam wurde.

<h2 id="common-statuses">
  Häufige Statuswerte
</h2>

| `extensions.status` | Bedeutung | Was zu tun ist |
| - | - | - |
| 400 | Ungültige Eingabe, die unsere API abgelehnt hat | Korrigieren Sie die Anfrage; eine Wiederholung hilft nicht |
| 401 | Fehlender oder ungültiger API Key | Prüfen Sie den `Authorization`-Header |
| 402 | Der Plan enthält diese Funktion nicht | Prüfen Sie Ihren Plan |
| 403 | Schlüssel gültig, aber für diese Aktion nicht berechtigt | Prüfen Sie Profile Keys und Plan |
| 404 | Das angeforderte Objekt existiert nicht | Überprüfen Sie die ID |
| 409 | Der Idempotenzschlüssel ist in Verwendung: Die erste Anfrage läuft noch, oder ein Boost-Schlüssel wurde mit anderen Argumenten verwendet | Läuft die erste Anfrage noch, warten Sie und wiederholen Sie unverändert; andernfalls verwenden Sie einen neuen Schlüssel für die neue Operation |
| 429 | Rate-Limit, Kontingent oder Dispatch-Budget | Nennt die Meldung das Dispatch-Budget, teilen Sie die Anfrage auf. Andernfalls warten Sie `retryAfter` ab oder warten schrittweise länger, falls der Wert fehlt |
| 500 | Auf unserer Seite ist etwas schiefgelaufen | Wiederholen Sie einen Lesevorgang (nicht `generatePost`, das erneut berechnet wird); verwenden Sie denselben Idempotenzschlüssel, wo unterstützt, andernfalls überprüfen Sie einen Schreibvorgang vor der Wiederholung |

Fehler, die GraphQL selbst vor der Ausführung auslöst, etwa ein unbekanntes Feld, ein falscher Argumenttyp oder ein ungültiger Enum-Wert, haben keinen `extensions.status`. Sie geben je nach Ihrem `Accept`-Header HTTP 400 oder 200 zurück, wie oben beschrieben. Sie bedeuten, dass die Query selbst falsch ist, und es wurde kein API-Aufruf ausgeführt oder berechnet.
