Gestion des erreurs en Rust : try/catch et bien plus — niveau avancé

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Gestion des erreurs en Rust : try/catch et bien plus — niveau avancé

\n\n

Contrairement à de nombreux langages où les exceptions sont un mécanisme standard (comme try/catch en Python, Java ou C++), Rust propose une approche fondamentalement différente. Il n'y a pas d'exceptions au sens classique du terme. À la place, le langage utilise un puissant système de types pour représenter et gérer les erreurs. Pour un débutant, cela peut sembler complexe, mais à un niveau avancé, vous apprécierez la sécurité et la prévisibilité qu'offre cette approche. Dans cet article, nous allons voir comment travailler professionnellement avec les erreurs en Rust : des bases Result et Option jusqu'aux crates avancés anyhow et thiserror, en passant par des parallèles avec le try/catch familier.

\n\n

1. Fondamentaux : Result, Option et l'opérateur ?

\n\n

La base de la gestion des erreurs en Rust est l'énumération Result<T, E>. Elle peut être soit Ok(T) (succès), soit Err(E) (erreur). L'équivalent de try/catch peut être considéré comme l'opérateur ?. Il simplifie la remontée d'erreur : si la valeur est Err, la fonction la retourne immédiatement ; si elle est Ok, elle extrait la valeur.

\n\n
use std::fs::File;\nuse std::io::Read;\n\nfn read_file(path: &str) -> Result<String, std::io::Error> {\n    let mut file = File::open(path)?; // Équivalent de try : remontée d'erreur\n    let mut content = String::new();\n    file.read_to_string(&mut content)?;\n    Ok(content)\n}
\n\n

Dans cet exemple, File::open et read_to_string peuvent retourner Err. L'opérateur ? remplace un match verbeux et rend le code aussi propre qu'un try/catch dans d'autres langages. Cependant, contrairement aux exceptions, vous spécifiez explicitement le type d'erreur dans la signature de la fonction — ce qui améliore la lisibilité et la sécurité.

\n\n

L'énumération Option<T> est utilisée pour les cas où une valeur peut être absente (équivalent de None en Python). L'opérateur ? fonctionne également avec elle :

\n\n
fn get_first_element(vec: &Vec<i32>) -> Option<&i32> {\n    vec.first()? // Si le vecteur est vide, on retourne None\n}
\n\n

2. Travail avancé avec les types d'erreur : les traits From et Error

\n\n

Lorsqu'une fonction appelle plusieurs opérations avec différents types d'erreur (par exemple, entrées-sorties et analyse syntaxique), un problème se pose : comment retourner un type unique ? La solution réside dans le trait From et un type d'erreur personnalisé.

\n\n

Créons notre propre structure d'erreur et implémentons pour elle le trait std::error::Error (automatiquement via #[derive(Debug)] et une implémentation manuelle de Display) :

\n\n
use std::fmt;\nuse std::io;\n\n#[derive(Debug)]\nenum MyError {\n    Io(io::Error),\n    Parse(std::num::ParseIntError),\n}\n\nimpl fmt::Display for MyError {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match self {\n            MyError::Io(e) => write!(f, "Erreur d'E/S : {}", e),\n            MyError::Parse(e) => write!(f, "Erreur d'analyse : {}", e),\n        }\n    }\n}\n\nimpl std::error::Error for MyError {}\n\n// Implémentons From pour une conversion automatique\nimpl From<io::Error> for MyError {\n    fn from(error: io::Error) -> Self {\n        MyError::Io(error)\n    }\n}\n\nimpl From<std::num::ParseIntError> for MyError {\n    fn from(error: std::num::ParseIntError) -> Self {\n        MyError::Parse(error)\n    }\n}\n\nfn process_data(path: &str) -> Result<i32, MyError> {\n    let content = std::fs::read_to_string(path)?; // Converti automatiquement en MyError::Io\n    let number: i32 = content.trim().parse()?;    // Converti automatiquement en MyError::Parse\n    Ok(number)\n}
\n\n

Maintenant, la fonction process_data retourne un type unique MyError, et l'opérateur ? convertit automatiquement les erreurs grâce au trait implémenté.

Blogs

Book Recommendations