Gestion des erreurs en Rust : try/catch et bien plus — guide complet

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 : abandon de try/catch au profit de la sécurité



Contrairement à Python ou Java, Rust ne possède pas de construction classique try/catch. Les développeurs du langage ont emprunté une autre voie, en faisant de la gestion des erreurs une partie du système de types. Ce n'est pas un caprice, mais une décision fondamentale qui permet de garantir la sécurité mémoire et la prévisibilité du programme dès la compilation. Dans cet article, nous allons passer en revue toutes les méthodes de gestion des erreurs en Rust : des Result et Option de base aux méthodes avancées avec l'opérateur ? et les types d'erreurs personnalisés.



1. Deux types principaux : Result et Option



En Rust, toutes les erreurs se divisent en deux catégories : les récupérables (traitées via Result) et les irrécupérables (conduisant à panic!). Il existe également le type Option pour les cas où une valeur peut être absente.



Le type Result



Result<T, E> est une énumération (enum) qui peut être soit Ok(T) (succès avec des données), soit Err(E) (erreur avec une description). C'est l'outil principal pour traiter les erreurs attendues : erreurs d'entrée-sortie, d'analyse, de requêtes réseau.



use std::fs::File;use std::io::Read;

fn read_file_content(path: &str) -> Result<String, std::io::Error> { let mut file = File::open(path)?; let mut content = String::new(); file.read_to_string(&mut content)?; Ok(content)}


Le type Option



Option<T> est une autre énumération qui prend les valeurs Some(T) (valeur présente) ou None (valeur absente). Elle est utilisée lorsque l'absence de données est une situation normale, et non une erreur.



fn find_user(id: u32) -> Option<String> {    let users = vec!["Alice".to_string(), "Bob".to_string()];    users.get(id as usize).cloned()}

fn main() { match find_user(0) { Some(name) => println!("Utilisateur trouvé : {}", name), None => println!("Utilisateur non trouvé"), }}


2. L'opérateur ? — une élégante alternative à try/catch



Si Rust avait un try/catch, il serait lourd. À la place, le langage propose l'opérateur ?. Il fonctionne ainsi : si le résultat est Ok, la valeur est extraite et transmise ; si c'est Err, l'erreur est immédiatement retournée depuis la fonction.



use std::num::ParseIntError;

fn parse_and_double(input: &str) -> Result<i32, ParseIntError> { let value: i32 = input.parse()?; // si erreur — return Err immédiat Ok(value * 2)}

fn main() { match parse_and_double("42") { Ok(result) => println!("Résultat : {}", result), Err(e) => println!("Erreur d'analyse : {}", e), }}


L'opérateur ? ne peut être utilisé que dans les fonctions qui retournent Result ou Option. Cela oblige le développeur à indiquer explicitement que la fonction peut échouer — contrairement aux exceptions en Python qui peuvent « surgir » de n'importe où.



3. Quand utiliser panic! et unwrap



Toutes les erreurs ne doivent pas être traitées. panic! est une macro pour les erreurs irrécupérables. Elle arrête le programme et déroule la pile (stack unwind). Utilisez-la uniquement dans des situations exceptionnelles :



  • États d'urgence : violation d'invariants impossibles à corriger.
  • Exemples et prototypes : dans du code pédagogique ou des scripts jetables.
  • Tests : pour vérifier que le code plante aux endroits attendus.


fn divide(a: i32, b: i32) -> i32 {    if b == 0 {        panic!("Division par zéro ! a={}, b={}", a, b);    }    a / b}


unwrap() et expect()

Blogs

Book Recommendations