> ## 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.

# Erreurs et nouvelles tentatives

> SquareCloudBlobError, la liste BlobErrorCode, les erreurs réseau qui ne sont pas encapsulées, et précisément quels appels @squarecloud/blob réessaie.

## `SquareCloudBlobError`

Chaque échec de l'API lève une `SquareCloudBlobError`.

| Propriété             | Type                      | Description                                                                                                                           |
| --------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `status`              | `number`                  | Statut HTTP de la réponse.                                                                                                            |
| `code`                | `BlobErrorCode`           | Le code d'erreur de l'API, par ex. `OBJECT_NOT_FOUND`.                                                                                |
| `message`             | `string`                  | L'explication du serveur, ou le code en l'absence d'explication.                                                                      |
| `extra`               | `Record<string, unknown>` | Tous les autres champs du corps de l'erreur, par ex. `prefix` sur les erreurs de règles.                                              |
| `isUpgradeRequired()` | `() => boolean`           | `true` pour `UPGRADE_REQUIRED`, le code de tous les refus liés au plan (limite, fonctionnalité ou plan). Le `message` précise lequel. |

```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
    }
}
```

### Ce qui n'est pas une `SquareCloudBlobError`

* **Les erreurs réseau ne sont pas encapsulées.** Lorsqu'une requête n'obtient pas de réponse complète (échec DNS, connexion réinitialisée, corps tronqué en cours de lecture), l'erreur `fetch` d'origine est levée telle quelle, après les éventuelles [nouvelles tentatives](#politique-de-nouvelles-tentatives).
* **Les erreurs de fichier.** Dans Node.js, un chemin `put()` qui ne peut pas être ouvert lève une `Error` simple (`Cannot open file: <path>`, erreur d'origine dans `cause`). Dans un navigateur, un chemin échoue avec l'erreur de l'import de `node:fs`.
* **Un `@aws-sdk/client-s3` manquant.** [`s3()`](/fr/sdks/blob/s3) lève l'erreur d'import du module.

### `UNKNOWN_ERROR`

`UNKNOWN_ERROR` est le **seul code que le SDK crée lui-même**. Il est utilisé lorsque la réponse n'a pas de code d'erreur : un corps non JSON (une page d'erreur de proxy, par exemple) ou une réponse `2xx` sans `status: "success"`. `status` contient toujours le vrai statut HTTP.

### Échecs par objet

Les opérations par lot signalent les échecs dans leur résultat au lieu de lever une erreur :

* [`update()`](/fr/sdks/blob/objects#mettre-à-jour-des-objets) : chaque résultat a `ok: false` et un `code`.
* [`delete([ids])`](/fr/sdks/blob/objects#supprimer) : les objets manquants vont dans `not_found`, les autres échecs dans `failed`.

## Codes d'erreur

`BlobErrorCode` est la liste de codes propre à l'API Blob Storage. Ce n'est **pas** la même liste que celle des codes d'erreur de l'API principale de Square Cloud. Pour le statut HTTP et la signification de chaque code, consultez la [référence des erreurs de l'API Blob](/fr/blob-reference/errors).

<AccordionGroup>
  <Accordion title="Globaux">
    `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` est **déprécié** : le service ne l'envoie plus (voir `RATE_LIMITED`), mais il reste dans le type.
  </Accordion>

  <Accordion title="Objets">
    `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="Envois multipart (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="Règles, jetons d'envoi, partages et 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="Validation (400)">
    Tout code `INVALID_*`, comme `INVALID_OBJECT`, `INVALID_OBJECT_NAME` ou `INVALID_RULE_PREFIX`. Les erreurs de règles portent le `prefix` fautif dans `error.extra`.
  </Accordion>

  <Accordion title="SDK">
    `UNKNOWN_ERROR` : la réponse n'avait pas de code d'erreur (voir [ci-dessus](#unknown_error)).
  </Accordion>
</AccordionGroup>

`BlobErrorCode` accepte aussi n'importe quelle autre chaîne, de sorte qu'un code ajouté ultérieurement par le service passe toujours la vérification de types.

## Politique de nouvelles tentatives

Le SDK ne réessaie que ce qui est **répétable sans risque** : les appels `GET` et les **parties** d'un envoi multipart (chaque numéro de partie peut être renvoyé).

| Réessayé                                     | Appels                                                                                                                                                                                               |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Oui**, jusqu'à `maxRetries` (2 par défaut) | `list()`, `listPage()`, `info()`, `downloadUrl()`, `stats()`, `rules.get()`, `shares.list()`, `s3Credentials()`, et chaque partie d'un `put()` multipart                                             |
| **Non**, une seule tentative                 | `put()` simple, démarrage, finalisation et annulation d'un envoi multipart, `update()`, `copy()`, `move()`, `delete()`, `rules.set()`, `uploadTokens.create()`, `shares.create()`, `shares.revoke()` |

Un appel réessayable est réessayé en cas de :

* **erreur réseau** (y compris un corps tronqué en cours de lecture) ;
* **toute réponse `5xx`** ;
* `TOO_MANY_CONCURRENT_CHUNKS` sur une partie multipart : le serveur refuse la partie avant de la lire, elle est donc renvoyée dans la limite du même budget.

Il n'est **jamais** réessayé pour tout autre `4xx`, **y compris `429`**. `RATE_LIMITED` peut être un blocage du compte d'environ 30 minutes, le SDK vous laisse donc la décision.

### Backoff

Avant la nouvelle tentative `n` (à partir de 0), le SDK attend :

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

Autrement dit, un backoff exponentiel plafonné à 8 secondes, avec un jitter compris entre 50 % et 100 % du délai. Avec la valeur par défaut `maxRetries: 2`, un appel fait au plus 3 tentatives.

### Réessayer vous-même les écritures

Une écriture qui échoue avec une erreur réseau ou un `5xx` a pu, ou non, être appliquée. Ne la réessayez que lorsque la répéter est sans risque pour vous, par exemple un `put()` vers le même `name` avec `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>
  Ne réessayez pas `429 RATE_LIMITED` dans une boucle serrée : dépasser le budget global du compte peut bloquer le compte pendant environ 30 minutes. Consultez la [référence des erreurs de l'API Blob](/fr/blob-reference/errors).
</Warning>

### Timeouts

Il n'y a pas de timeout côté client et aucun moyen d'annuler un appel : une requête dure aussi longtemps que `fetch` attend.
