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

# Fehler und Wiederholungen

> SquareCloudBlobError, die Liste BlobErrorCode, Netzwerkfehler, die nicht verpackt werden, und welche Aufrufe @squarecloud/blob genau wiederholt.

## `SquareCloudBlobError`

Jeder API-Fehler wirft einen `SquareCloudBlobError`.

| Eigenschaft           | Typ                       | Beschreibung                                                                                                                   |
| --------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `status`              | `number`                  | HTTP-Status der Antwort.                                                                                                       |
| `code`                | `BlobErrorCode`           | Der Fehlercode der API, z. B. `OBJECT_NOT_FOUND`.                                                                              |
| `message`             | `string`                  | Die Erklärung des Servers, oder der Code, wenn es keine gibt.                                                                  |
| `extra`               | `Record<string, unknown>` | Jedes weitere Feld des Fehler-Bodys, z. B. `prefix` bei Regelfehlern.                                                          |
| `isUpgradeRequired()` | `() => boolean`           | `true` bei `UPGRADE_REQUIRED`, dem Code jeder planbedingten Ablehnung (Limit, Funktion oder Plan). Die `message` sagt, welche. |

```typescript theme={"system"}
import { SquareCloudBlob, SquareCloudBlobError } from "@squarecloud/blob";

const blob = new SquareCloudBlob(process.env.SQUARECLOUD_API_KEY);

try {
    await blob.shares.create(id, { password: "secret123" });
} catch (error) {
    if (error instanceof SquareCloudBlobError) {
        if (error.isUpgradeRequired()) {
            console.error(error.message); // your plan lacks this feature or limit
        } else if (error.code === "OBJECT_NOT_FOUND") {
            // ...
        } else {
            console.error(error.status, error.code, error.extra);
        }
    } else {
        throw error; // network error or file error, see below
    }
}
```

### Was kein `SquareCloudBlobError` ist

* **Netzwerkfehler werden nicht verpackt.** Erhält eine Anfrage keine vollständige Antwort (DNS-Fehler, Verbindung zurückgesetzt, Body mitten im Lesen abgeschnitten), wird der ursprüngliche `fetch`-Fehler unverändert geworfen, nach eventuellen [Wiederholungen](#wiederholungsrichtlinie).
* **Dateifehler.** In Node.js wirft ein `put()`-Pfad, der sich nicht öffnen lässt, einen einfachen `Error` (`Cannot open file: <path>`, ursprünglicher Fehler in `cause`). Im Browser schlägt ein Pfad mit dem Fehler beim Import von `node:fs` fehl.
* **Ein fehlendes `@aws-sdk/client-s3`.** [`s3()`](/de/sdks/blob/s3) wirft den Importfehler des Moduls.

### `UNKNOWN_ERROR`

`UNKNOWN_ERROR` ist der **einzige Code, den das SDK selbst erzeugt**. Er wird verwendet, wenn die Antwort keinen Fehlercode hat: ein Body, der kein JSON ist (zum Beispiel die Fehlerseite eines Proxys), oder eine `2xx`-Antwort ohne `status: "success"`. `status` enthält weiterhin den echten HTTP-Status.

### Fehler einzelner Objekte

Batch-Operationen melden Fehler in ihrem Ergebnis, statt zu werfen:

* [`update()`](/de/sdks/blob/objects#objekte-aktualisieren): Jedes Ergebnis hat `ok: false` und einen `code`.
* [`delete([ids])`](/de/sdks/blob/objects#löschen): Fehlende Objekte landen in `not_found`, andere Fehler in `failed`.

## Fehlercodes

`BlobErrorCode` ist die eigene Liste von Codes der Blob Storage API. Sie ist **nicht** dieselbe Liste wie die Fehlercodes der Haupt-API von Square Cloud. HTTP-Status und Bedeutung jedes Codes findest du in der [Fehlerreferenz der Blob API](/de/blob-reference/errors).

<AccordionGroup>
  <Accordion title="Global">
    `ACCESS_DENIED`, `RATE_LIMITED`, `MISSING_SCOPE`, `RESOURCE_NOT_ALLOWED`, `UPLOAD_TOKEN_NOT_ALLOWED`, `UPLOAD_TOKEN_USED`, `PREFIX_NOT_ALLOWED`, `PERMISSION_DENIED`, `ACCOUNT_BLOCKED`, `UPGRADE_REQUIRED`, `STORAGE_QUOTA_EXCEEDED`, `PRIVATE_STORAGE_UNAVAILABLE`, `PUBLIC_STORAGE_UNAVAILABLE`, `TOO_MANY_CONCURRENT_UPLOADS`, `UPLOAD_FAILED`, `INTERNAL_SERVER_ERROR`, `NOT_FOUND`

    `RATE_LIMIT` ist **veraltet**: Der Dienst sendet ihn nicht mehr (siehe `RATE_LIMITED`), er bleibt aber im Typ.
  </Accordion>

  <Accordion title="Objekte">
    `OBJECT_NOT_FOUND`, `OBJECT_ALREADY_EXISTS`, `OBJECT_IS_LEGACY`, `CHECKSUM_MISMATCH`, `INVALID_CONTENT_TYPE`, `FILE_TOO_LARGE`, `FILE_TOO_SMALL`, `BLOCKED_FILE_TYPE`, `INVALID_FILE_TYPE`, `FILE_TYPE_NOT_ALLOWED`, `NOTHING_TO_UPDATE`, `VISIBILITY_CHANGE_FAILED`, `UPDATE_FAILED`, `DELETE_FAILED`, `TOO_MANY_OBJECTS`, `SAME_OBJECT`, `INVALID_DESTINATION`, `COPY_FAILED`, `PREFIX_REQUIRED`, `INVALID_CONTINUATION_TOKEN`
  </Accordion>

  <Accordion title="Multipart-Uploads (Chunked)">
    `TOO_MANY_CONCURRENT_CHUNKS`, `TOO_MANY_OPEN_UPLOADS`, `INVALID_UPLOAD_TOKEN`, `UPLOAD_NOT_FOUND`, `NO_CHUNKS_UPLOADED`, `EMPTY_CHUNK`, `INVALID_CHUNK_PART`, `CHUNK_TOO_SMALL`, `CHUNK_TOO_LARGE`
  </Accordion>

  <Accordion title="Regeln, Upload-Tokens, Freigaben und S3">
    `TOO_MANY_RULES`, `DUPLICATE_RULE_PREFIX`, `INVALID_RULES`, `UPLOAD_TOKEN_TOO_LARGE`, `TOO_MANY_SHARES`, `SHARE_NOT_FOUND`, `INVALID_SHARE`, `API_KEY_REQUIRED`, `LEGACY_API_KEY`
  </Accordion>

  <Accordion title="Validierung (400)">
    Jeder `INVALID_*`-Code, etwa `INVALID_OBJECT`, `INVALID_OBJECT_NAME` oder `INVALID_RULE_PREFIX`. Regelfehler enthalten das betroffene `prefix` in `error.extra`.
  </Accordion>

  <Accordion title="SDK">
    `UNKNOWN_ERROR`: Die Antwort hatte keinen Fehlercode (siehe [oben](#unknown_error)).
  </Accordion>
</AccordionGroup>

`BlobErrorCode` akzeptiert außerdem jeden anderen String, sodass ein Code, den der Dienst später hinzufügt, trotzdem die Typprüfung besteht.

## Wiederholungsrichtlinie

Das SDK wiederholt nur, was sich **gefahrlos wiederholen lässt**: `GET`-Aufrufe und **Teile** von Multipart-Uploads (jede Teilnummer kann erneut gesendet werden).

| Wiederholt                               | Aufrufe                                                                                                                                                                                                 |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Ja**, bis zu `maxRetries` (Standard 2) | `list()`, `listPage()`, `info()`, `downloadUrl()`, `stats()`, `rules.get()`, `shares.list()`, `s3Credentials()` und jeder Teil eines Multipart-`put()`                                                  |
| **Nein**, ein einziger Versuch           | Einfaches `put()`, Starten, Abschließen und Abbrechen eines Multipart-Uploads, `update()`, `copy()`, `move()`, `delete()`, `rules.set()`, `uploadTokens.create()`, `shares.create()`, `shares.revoke()` |

Ein wiederholbarer Aufruf wird wiederholt bei:

* einem **Netzwerkfehler** (einschließlich eines mitten im Lesen abgeschnittenen Bodys);
* **jeder `5xx`**-Antwort;
* `TOO_MANY_CONCURRENT_CHUNKS` bei einem Multipart-Teil: Der Server lehnt den Teil ab, bevor er ihn liest, daher wird er innerhalb desselben Budgets erneut gesendet.

Er wird **nie** bei einem anderen `4xx` wiederholt, **einschließlich `429`**. `RATE_LIMITED` kann eine Kontosperre sein, die etwa 30 Minuten dauert, daher überlässt das SDK die Entscheidung dir.

### Backoff

Vor Wiederholung `n` (ab 0) wartet das SDK:

```text theme={"system"}
min(8 s, 500 ms · 2^n) · U(0.5, 1)
```

Das heißt: exponentielles Backoff mit einer Obergrenze von 8 Sekunden und Jitter zwischen 50 % und 100 % der Verzögerung. Mit dem Standardwert `maxRetries: 2` macht ein Aufruf höchstens 3 Versuche.

### Schreibvorgänge selbst wiederholen

Ein Schreibvorgang, der mit einem Netzwerkfehler oder einem `5xx` fehlschlägt, wurde möglicherweise angewendet, möglicherweise auch nicht. Wiederhole ihn nur, wenn das für dich gefahrlos ist, zum Beispiel ein `put()` auf denselben `name` mit `overwrite: true`.

```typescript theme={"system"}
import { SquareCloudBlobError } from "@squarecloud/blob";

async function putWithRetry(file, options, attempts = 3) {
    for (let i = 0; ; i++) {
        try {
            return await blob.put(file, { ...options, overwrite: true });
        } catch (error) {
            // fetch network errors are TypeErrors; 5xx are SquareCloudBlobErrors
            const retryable =
                error instanceof SquareCloudBlobError
                    ? error.status >= 500
                    : error instanceof TypeError;
            if (!retryable || i + 1 >= attempts) throw error;
            await new Promise((r) => setTimeout(r, 1000 * 2 ** i));
        }
    }
}
```

<Warning>
  Wiederhole `429 RATE_LIMITED` nicht in einer engen Schleife: Eine Überschreitung des kontoweiten Budgets kann das Konto für etwa 30 Minuten sperren. Siehe die [Fehlerreferenz der Blob API](/de/blob-reference/errors).
</Warning>

### Timeouts

Es gibt kein Client-Timeout und keine Möglichkeit, einen Aufruf abzubrechen: Eine Anfrage dauert so lange, wie `fetch` wartet.
