colisdocs

Erreurs

Les codes d’erreur stables de la bibliothèque, du protocole et de la page de livraison, et quoi en faire.

colis a trois familles d’erreurs, chacune avec un code stable sur lequel brancher plutôt que sur un statut HTTP ou le texte d’un message.

Dans la bibliothèque : ColisError

Tout ce que lève @colis/core est une ColisError, avec un code et l’erreur d’origine dans cause :

import { isColisError } from '@colis/core'

try {
  await store.upload(file)
} catch (error) {
  if (isColisError(error)) console.error(error.code, error.message, error.cause)
  throw error
}
CodeQuand
INVALID_CONFIGBucket manquant, publicUrl qui n’est pas une URL absolue, maxSize non positif, forme de code invalide.
INVALID_SYNC_CODELe code est vide, ou contient un caractère hors de l’alphabet.
INVALID_KEYClé vide, / en début ou en fin, segment .., antislash, caractère de contrôle, plus de 1 024 octets.
INVALID_BODYLe corps envoyé n’est pas d’un type pris en charge.
MISSING_CONTENT_LENGTHUn flux envoyé sans contentLength.
FILE_TOO_LARGELe corps dépasse maxSize.
UPLOAD_FAILEDPutObject ou un envoi en morceaux a été refusé. Erreur d’origine dans cause.
GET_FAILEDGetObject ou HeadObject a échoué pour une autre raison qu’une clé absente.
DELETE_FAILEDDeleteObject ou DeleteObjects a été refusé, ou S3 a signalé des échecs par clé.
URL_FAILEDexpiresIn invalide, échec de signature, ou URL publique demandée sans publicUrl.
PRECONDITION_FAILEDUne écriture ifMatch ou ifAbsent a perdu la course.
INVALID_SNAPSHOTUn enregistrement JSON illisible, ou des données que JSON ne sait pas représenter.
SNAPSHOT_TOO_NEWUn enregistrement écrit par un schéma plus récent que maxVersion.

INVALID_CONFIG, INVALID_SYNC_CODE, INVALID_KEY, INVALID_BODY, MISSING_CONTENT_LENGTH et FILE_TOO_LARGE sont levées avant qu’un seul octet ne parte : un code absurde collé dans un champ coûte une comparaison, pas une requête.

Une clé absente n’est pas une erreur : get(), head() et getSnapshot() renvoient null, et delete() sur une clé absente réussit sans bruit.

Sur le fil : TransferError

Les routes du protocole répondent { error: { code, message } }, et le client de @colis/protocol (donc la CLI, les hooks React et le nœud n8n) lève une TransferError avec ce code : INVALID_REQUEST, INVALID_SYNC_CODE, UNAUTHORIZED, NOT_FOUND, CODE_TAKEN, SNAPSHOT_TOO_NEW, TOO_LARGE, INTERNAL.

import { isTransferError } from '@colis/protocol'

if (isTransferError(error) && error.code === 'NOT_FOUND') {
  // code inconnu ou expiré : les deux sont indiscernables, exprès
}

Sur la page de livraison

Ses routes propres gardent la même forme de réponse, avec quelques codes en plus :

CodeHTTPQuand
UNAUTHORIZED401DROP_PASSWORD manquant ou faux à l’envoi, ou colis protégé sans son mot de passe. L’en-tête x-drop-protected: 1 distingue le second cas.
FORBIDDEN403L’expéditeur essaie de répondre à la place du client.
NOT_FOUND404Code inconnu ou expiré, colis à usage unique déjà téléchargé, ou aucun accusé.
ALREADY_DECIDED409Le colis a déjà reçu une réponse ; elle est définitive.
TOO_LARGE413Fichier au-delà de DROP_MAX_SIZE_MB en une requête, ou de DROP_MAX_UPLOAD_MB en morceaux (DROP_OPEN_MAX_UPLOAD_MB sans mot de passe).
RATE_LIMITED429Trop de mauvais mots de passe (le code est verrouillé), ou, sans DROP_PASSWORD, trop d’envois depuis une adresse (DROP_UPLOADS_PER_HOUR). retry-after dit combien de secondes.

Les routes des comptes ajoutent les leurs :

CodeHTTPQuand
ACCOUNTS_DISABLED503Le déploiement n’a pas d’e-mail configuré (RESEND_API_KEY, COLIS_MAIL_FROM) : personne ne se connecte.
UNAUTHENTICATED401Aucune session sur GET /api/me, ou confirmation d’un code de terminal sans être connecté.
INVALID_SESSION401Un jeton Bearer colis_… inconnu, expiré ou révoqué, y compris sur un envoi : jamais d’envoi anonyme à la place.
INVALID_LINK400Un lien de connexion déjà utilisé ou expiré (15 minutes).
INVALID_DEVICE_CODE400Un code de terminal inconnu, expiré (10 minutes) ou déjà échangé.
FORBIDDEN_ORIGIN403Une requête qui modifie la session depuis un autre site que le déploiement.
MAIL_FAILED502Resend a refusé l’e-mail, ou n’a pas répondu.

La formule Pro ajoute les siens :

CodeHTTPQuand
PLAN_LIMIT403Un envoi au-delà de la formule gratuite que Pro accepterait : fichier trop gros, ou durée trop longue. details dit laquelle : { limit, max, pro }.
BILLING_DISABLED503Le déploiement ne vend pas Pro : une des quatre variables STRIPE_* manque, ou les comptes sont désactivés.
ALREADY_PRO409Un paiement demandé pour un compte déjà Pro.
NO_SUBSCRIPTION404L’espace d’abonnement demandé pour un compte qui n’a jamais souscrit.
BILLING_FAILED502Stripe a refusé la demande, ou n’a pas répondu.
INVALID_SIGNATURE400Un webhook dont la signature Stripe-Signature ne correspond pas, ou date de plus de cinq minutes.
{
  "error": {
    "code": "PLAN_LIMIT",
    "message": "Ce fichier dépasse 100 Mo, la limite de la formule gratuite. La formule Pro accepte jusqu’à 2 Go.",
    "details": { "limit": "size", "max": 104857600, "pro": 2147483648 }
  }
}

Les messages de ces routes sont en français, prêts à être affichés au client.

Dans la CLI

La CLI sort avec le code 1 à chaque échec, et distingue ce qu’il faut faire :

  • une erreur d’usage (commande inconnue, fichier absent, bucket non configuré) s’affiche avec une piste de correction en dessous ;
  • une erreur du protocole ou de la bibliothèque s’affiche avec son code, par exemple NOT_FOUND: Unknown or expired code. ;
  • INVALID_CONFIG rappelle que colis config montre ce que la configuration a résolu ;
  • PLAN_LIMIT rappelle que la formule Pro va plus loin : colis compte pro.

En cas de doute, colis verifier effectue chaque opération et dit laquelle échoue.

Sur cette page