En Rust, il n'y a pas d'exceptions comme en Java ou C++; à la place, on utilise les types d'enveloppe Result et Option pour renvoyer des erreurs.
Result<T, E> — stocke soit une valeur (Ok(T)), soit une erreur (Err(E)). Il est généralement utilisé pour des opérations qui peuvent ne pas s'exécuter correctement (par exemple, l’entrée/sortie de fichiers).
Option<T> — pour les valeurs optionnelles : soit Some(T), soit None, sans information sur l'erreur. Exemple:
fn divide(x: f64, y: f64) -> Option<f64> { if y == 0.0 { None } else { Some(x / y) } }
En Rust, il n'y a pas d'exceptions au style try/catch pour garantir un flux d'erreurs transparent et géré, sans nécessiter de ramasse-miettes ou de moteur de désenroulement pour maintenir les exceptions.
Pourquoi panic! ne peut-il pas être utilisé pour une gestion normale des erreurs ?
Réponse : panic! termine le flux d'exécution, ne permet pas de se rétablir, et entraîne un unwinding/abort. Si les erreurs sont renvoyées via Result, la partie appelante peut les traiter. Exemple :
fn foo() -> Result<(), String> { Err("Quelque chose a mal tourné".to_string()) } // au lieu de fn foo() { panic!("Quelque chose a mal tourné"); }
Histoire
Dans un microservice de traitement d'images, le développeur a utilisé
panic!pour gérer toutes les situations imprévues. Cela entraînait l'arrêt brutal du service lors de toute erreur au lieu de renvoyer une réponse HTTP correcte au client avec les détails de l'erreur.
Histoire
Dans un outil CLI,
unwrap()était utilisé pour toutes les entrées/sorties, sans traiter les erreurs éventuelles. En conséquence, lors d'une erreur de système de fichiers, le programme se terminait simplement sans aucun message ou diagnostic.
Histoire
Dans un service d'analyse, ils ont tenté d'utiliser Option pour chaque petite erreur, se privant d'informations sur les erreurs elles-mêmes, rendant le débogage difficile. Après être passé à Result avec des erreurs d’énumération, il est devenu plus facile de trouver et de corriger des bugs.