Gestion des erreurs en Rust : try/catch et au-delà

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
```html

Introduction : la philosophie de la gestion des erreurs en Rust



Contrairement à de nombreux langages utilisant des exceptions (Java, Python, C++), Rust n'utilise pas la construction classique try/catch. Le langage propose plutôt une approche plus explicite et type-safe. Les erreurs en Rust ne sont pas des flux de contrôle cachés, mais des valeurs de retour. Cela rend le code prévisible et protège contre les pannes « silencieuses ».



Rust dispose de deux types principaux pour représenter les situations d'erreur :

  • Result<T, E> — pour les erreurs récupérables (erreurs d'entrée-sortie, d'analyse syntaxique, de logique métier).
  • Option<T> — pour l'absence de valeur (analogue à null, mais sécurisé).


Dans cet article, nous allons voir comment travailler avec ces types, comment les substituer au monde du try/catch, et comment écrire du code fiable en Rust.



1. Result<T, E> : l'outil principal de gestion des erreurs



Le type Result est une énumération avec deux variantes : Ok(T) (succès) et Err(E) (erreur). Il est utilisé dans la plupart des fonctions qui peuvent échouer.



1.1. Création et retour d'un Result



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

fn read_file(path: &str) -> Result<String, std::io::Error> { let mut file = File::open(path)?; // l'opérateur ? — analogue à try ! let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(contents)}


Ici, l'opérateur ? est un élément clé. Il fonctionne comme try dans d'autres langages : si le résultat est Err, la fonction retourne immédiatement cette erreur. Si c'est Ok, il extrait la valeur.



1.2. Gestion avec match



La manière la plus explicite est d'utiliser match :



let result = read_file("config.txt");

match result { Ok(content) => println!("Fichier lu : {}", content), Err(e) => eprintln!("Erreur : {}", e),}


C'est un analogue de try/catch, mais plus flexible et contrôlé.



1.3. Méthodes auxiliaires



  • .unwrap() — panique en cas d'erreur (uniquement pour les prototypes).
  • .expect(msg) — panique avec un message personnalisé.
  • .unwrap_or(default) — retourne une valeur par défaut.
  • .is_ok() / .is_err() — vérification de l'état.


2. Option<T> : travail sécurisé avec l'absence de valeur



Option est une autre énumération avec les variantes Some(T) et None. Elle remplace null et nullptr, éliminant les erreurs de déréférencement de pointeur nul.



2.1. Exemple d'utilisation



fn find_user(id: u32) -> Option<String> {    if id == 1 {        Some("Alice".to_string())    } else {        None    }}

let user = find_user(2);println!("Utilisateur : {}", user.unwrap_or("Invité".to_string()));


2.2. Combinaison avec Result



Il est fréquent de convertir Option en Result pour un traitement uniforme :



fn get_user_name(id: u32) -> Result<String, String> {    find_user(id).ok_or("Utilisateur non trouvé".to_string())}


La méthode .ok_or() transforme Some en Ok, et None en Err.



3. L'opérateur ? : un remplacement élégant de try/catch



L'opérateur ? est un sucre syntaxique qui dépaquette automatiquement un Result ou un Option. Il n'est disponible que dans les fonctions retournant le type correspondant.



3.1. Exemple avec une chaîne d'appels



use std::num::ParseIntError;

fn parse_and_add(a: &str, b: &str) -> Result<i32, ParseIntError> { let x: i32 = a.parse()?; let y: i32 = b.parse()?; Ok(x ```

Blogs

Book Recommendations