Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Modèle d’erreurs (AirStatus)

Air rend ses erreurs in-band : la valeur de retour porte le statut. Pas d’errno, pas d’exception, aucune panic qui traverse l’ABI. Cette page explique comment tester, lire et propager ces statuts — et pourquoi ce modèle a été choisi (ADR-045).

La règle de base

Presque toute fonction rend un enum AirStatus. AIR_STATUS_OK == 0 est le seul cas de succès, et le seul cas où un *out est écrit :

AirUuid u;
AirStatus st = air_uuid_new_v7(&u);
if (st != AIR_STATUS_OK) {
  /* `u` n'a PAS été écrit — ne pas le lire. */
  fprintf(stderr, "échec : %s\n", air_status_message(st));
  return 1;
}
/* Ici seulement, `u` est valide. */

Piège. Ne lisez jamais un paramètre de sortie avant d’avoir vérifié AIR_STATUS_OK. Sur erreur, *out est laissé intact (non initialisé si vous ne l’aviez pas initialisé). C’est volontaire : zéro écriture partielle.

Lire un statut : air_status_message

const char *msg = air_status_message(st);   /* jamais NULL */

La chaîne est statique (strerror-like, sans locale ni état global) : valide pour toute la durée du programme, à ne pas libérer. C’est un message technique en anglais, destiné aux logs/diagnostics — pas un texte localisé pour l’utilisateur final.

Le catalogue des statuts

Deux familles, aux discriminants committés (ADR-012) :

PlageOrigineExemples
0succèsAIR_STATUS_OK
1..=13miroir de AirErrorKind (couche 1)AIR_STATUS_NOT_FOUND, AIR_STATUS_INVALID_DATA, AIR_STATUS_IO
100, 101propres à la frontière CAIR_STATUS_NULL_ARGUMENT, AIR_STATUS_BUFFER_TOO_SMALL

Les deux statuts de frontière sont ceux que vous pouvez déclencher par un mauvais usage de l’API :

  • AIR_STATUS_NULL_ARGUMENT (100) — un pointeur requis valait NULL. Détecté par validation amont, sans déréférencement : passer NULL ne provoque jamais de segfault côté Air, juste ce statut. (Les fonctions de libération air_log_close/air_log_fields_free font exception : NULL y est un no-op documenté, pas une erreur.)
  • AIR_STATUS_BUFFER_TOO_SMALL (101) — votre buffer de sortie est trop petit. Rien n’est écrit (pas de troncature silencieuse, ADR-032). Agrandissez le buffer aux constantes du header et rappelez.

Pourquoi pas d’errno ?

errno est un état global par thread, fragile : facile à écraser entre l’appel et sa lecture, invisible dans la signature, source de bugs classiques en C. Le statut in-band est au contraire :

  • explicite dans le type de retour (impossible de l’ignorer par mégarde) ;
  • local (aucun état partagé, donc trivialement thread-safe) ;
  • stable (discriminants committés).

Pourquoi aucune panic ne traverse l’ABI

La crate est compilée en panic = "abort". Conséquence : une panic Rust ne se propage pas à travers la frontière C (ce serait un comportement indéfini) — elle avorte le processus immédiatement (fail-fast). Autrement dit :

  • une panic = un bug dans Air, jamais une condition d’erreur normale ;
  • les conditions attendues (entrée invalide, ressource absente, buffer court) sont toutes rendues via AirStatus, jamais par panic ;
  • vous n’avez aucun catch à écrire côté C, et aucun AIR_PANIC à gérer : le contrat est « soit AirStatus, soit le processus s’arrête ».

C’est un choix de sûreté : mieux vaut un abort net et diagnosticable qu’un déroulement de pile qui corromprait l’état d’un appelant C.

Propager proprement

Comme AirStatus est une valeur, la propagation est triviale : relayez le statut, ou mappez-le sur votre propre modèle d’erreurs. Schéma typique :

AirStatus do_work(AirLog *log) {
  AirInstant t0;
  AirStatus st = air_instant_now(&t0);
  if (st != AIR_STATUS_OK) {
    return st;            /* remonte tel quel */
  }
  /* … */
  return AIR_STATUS_OK;
}

English version: Error model.