Bibliothèques de Gestion d'Erreurs en Rust

  • thiserror fournit des macros dérivées pratiques pour les types d'erreur personnalisés.

  • snafu est un framework de gestion et de signalisation d'erreurs avec contexte.

  • anyhow est une bibliothèque flexible de gestion et de signalisation d'erreurs.

thiserror vs snafu

thiserror

thiserror est une bibliothèque légère qui fournit des macros dérivées pour simplifier les définitions d'erreurs.

Caractéristiques :

  • Syntaxe concise avec peu de formalités
  • Adapté à la création de bibliothèques de types d'erreur et d'APIs
  • Généralement utilisé pour créer des bibliothèques destinées à d'autres
use thiserror::Error;

#[derive(Error, Debug)]
pub enum DataError {
    #[error("Erreur de base de données : {0}")]
    DatabaseError(#[from] sqlx::Error),
    
    #[error("Erreur de validation : {0}")]
    ValidationError(String),
    
    #[error("Enregistrement non trouvé")]
    NotFound,
}

snafu

snafu fournit un framework de gestion d'erreurs plus complet axé sur le contexte d'erreur et l'enchaînement des erreurs.

Caractéristiques :

  • Encourage l'ajout de contexte d'erreur plus précis via le modèle "sélecteur de contexte"
  • Favorise le modèle "une énumération d'erreur par module"
  • Prend en charge les variantes d'erreur de type struct et tuple
  • Prise en charge intégrée des backtraces
use snafu::{Snafu, ResultExt, Backtrace};

#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("Échec de lecture du fichier de configuration {filename:?}"))]
    ReadConfig {
        filename: String,
        source: std::io::Error,
        backtrace: Backtrace,
    },
    
    // Le style tuple est également pris en charge
    #[snafu(display("Erreur d'E/S"))]
    Io(#[snafu(source)] std::io::Error, #[snafu(backtrace)] Backtrace),
}

// Exemple de sélecteur de contexte
fn read_config(path: &str) -> Result<Config, Error> {
    std::fs::read_to_string(path).context(ReadConfigSnafu { filename: path })?;
    // ...
}

Comparaison

Caractéristiquethiserrorsnafu
Concision syntaxiquePlus concisPlus verbeux
Contexte d'erreurSupport basiqueMécanismes de contexte riches
Échelle adaptéePetits à moyens projetsMoyens à grands projets
Lignes par erreur~2 lignes par erreur~5 lignes par erreur
Organisation des erreursGénéralement une seule énumération d'erreurEncourage les énumérations d'erreur par module
Support des backtracesPas de support intégréSupport intégré

Conseils de sélection :

  • Choisissez thiserror lorsque vous avez besoin de types d'erreur simples et clairs, particulièrement dans les bibliothèques
  • Choisissez snafu lorsque vous avez besoin d'une gestion d'erreurs plus structurée, notamment dans les grandes applications

anyhow

anyhow est une bibliothèque de gestion d'erreurs différente des deux précédentes, axée sur les applications plutôt que sur les bibliothèques.

Caractéristiques :

  • Conçue pour la gestion d'erreurs dans les applications, pas dans les bibliothèques
  • Fournit un type dynamique anyhow::Error qui peut contenir toute erreur implémentant le trait Error
  • Simplifie la gestion de multiples types d'erreurs
  • Pas besoin de définir des types d'erreur personnalisés
use anyhow::{Context, Result};

fn main() -> Result<()> {
    let config = std::fs::read_to_string("config.json")
        .context("Échec de lecture du fichier de configuration")?;
        
    let app_config: AppConfig = serde_json::from_str(&config)
        .context("Format de configuration invalide")?;
        
    // Utilisation de Result<T> comme alias de type pour Result<T, anyhow::Error>
    Ok(())
}

anyhow vs thiserror/snafu :

  • anyhow se concentre sur la gestion d'erreurs pendant le développement rapide d'applications
  • thiserror/snafu se concentrent sur la création de hiérarchies précises de types d'erreur
  • anyhow est généralement utilisé dans le code d'application
  • thiserror/snafu sont généralement utilisés dans le code de bibliothèque

En pratique, anyhow et thiserror sont souvent utilisés ensemble : les bibliothèques utilisent thiserror pour définir des types d'erreur précis, tandis que les applications utilisent anyhow pour gérer les erreurs provenant de diverses sources.