Toutes les exceptions en Dart sont des exceptions non vérifiées : nul besoin de déclarer le type levé dans une fonction, et leur capture n’est pas obligatoire.
On distingue deux catégories principales :
Exception: Erreurs prévisibles liées à la logique métier (problèmes de format, paramètres invalides… Il est recommandé de les intercepter pour les traiter).Error: Erreurs fatales du programme (incompatibilités de type, pointeur nul, méthodes non implémentées… Généralement, on ne les capture pas).
Tout objet non nul peut être levé avec le mot-clé throw. Sur des projets structurés, on ne lève que des sous-classes de Exception/Error.
Toute exception non interceptée arrête l’isolate en cours et provoque le plantage de l’application.
throw : lever une exception
1. Lever une exception native du système
void main() {
// Exception de format
throw FormatException("Au moins un segment de données est requis");
}
Langage du code : Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
FormatException: Description de l'erreur
#0 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:3:3)
#1 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Langage du code : HTML, XML (xml)
Ce code permet de lever une exception native avec un message personnalisé qui s’affichera à l’exécution. On pourrait se demander à quoi cela sert, mais la levée d’exceptions est un mécanisme indispensable au développement. Par exemple, lors d’une inscription utilisateur, on valide le format des saisies : si elles ne respectent pas les règles, on lève immédiatement une exception pour interrompre le processus et avertir l’utilisateur. Cela empêche l’insertion de données invalides et préserve l’intégrité des informations stockées.
2. Lever n’importe quel objet
Non recommandé pour un environnement de production
void main() {
throw "Texte descriptif de l'erreur !";
}Langage du code : Dart (dart)
Résultat de l’exécution
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
Texte descriptif de l'erreur !
#0 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:2:3)
#1 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Langage du code : HTML, XML (xml)
3. Utiliser throw dans une fonction fléchée (throw est une expression)
class Point {}
void distanceTo(Point other) => throw UnimplementedError("Cette méthode n'a pas été implémentée");
void main() {
distanceTo(Point());
}
Langage du code : JavaScript (javascript)
III. Intercepter des exceptions avec try /on/catch
Différences de syntaxe
on TypeException: Ne correspond qu’aux exceptions du type indiqué, impossible de récupérer l’objet exception.catch(e): Intercepte toutes les exceptions, la variable e contient l’instance de l’exception.catch(e, s): e = objet de l’exception, s = pile d’appels StackTrace.
1 : Intercepter un seul type d’exception avec on
// Créer une classe d'exception personnalisée qui implémente Exception
class OutOfLlamasException implements Exception {}
// Fonction qui lève notre exception personnalisée
void breedMoreLlamas() {
throw OutOfLlamasException();
}
void buyMoreLlamas() {
print("La fonction buyMoreLlamas s'est exécutée");
}
void main() {
try {
breedMoreLlamas(); // Appel de la fonction à risque
} on OutOfLlamasException {
buyMoreLlamas(); // S'exécute si OutOfLlamasException est interceptée
}
}Langage du code : Dart (dart)
Résultat de l’exécution
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
La fonction buyMoreLlamas s'est exécutée
try {
// Code susceptible de produire une erreur
} on TypeException {
// Traitement à exécuter si l'erreur est interceptée
}Langage du code : Dart (dart)
try on est simplement une syntaxe dédiée à l’interception d’exceptions par type.
2 : Interception à plusieurs niveaux par branches
Les correspondances les plus précises sont traitées en priorité
class OutOfLlamasException implements Exception {}
void breedMoreLlamas() {
throw FormatException("Format de données incorrect");
}
void main() {
try {
breedMoreLlamas();
}
// 1. Correspondance exacte avec l'exception personnalisée
on OutOfLlamasException {
print("Erreur : OutOfLlamasException");
}
// 2. Intercepter toutes les sous-classes d'Exception
on Exception catch (e) {
print("Exception métier classique : $e");
}
// 3. Cas de secours pour les Error et tout autre objet levé
catch (e) {
print("Erreur grave inconnue : $e");
}
}
Langage du code : Dart (dart)
Sortie : Exception métier classique : FormatException: Format de données incorrect
On peut utiliser plusieurs blocs on pour intercepter séparément chaque type d’Exception, complétés par un catch final en tant que filet de sécurité.
3 : Intercepter une exception et afficher la pile d’appels StackTrace
void main() {
try {
int a = null;
print(a + 1);
} catch (e, stack) {
print("Message de l'exception : $e");
print("Pile d'appels complète :\n$stack");
}
}
Langage du code : Dart (dart)
Ce code affiche non seulement le message d’erreur, mais aussi l’intégralité de la chaîne d’appel des fonctions pour faciliter le débogage.
D:\dartdemo\firstdart>dart run
Building package executable...
Failed to build firstdart:firstdart:
bin/firstdart.dart:3:13: Error: A value of type 'Null' can't be assigned to a variable of type 'int'.
int a = null;Langage du code : PHP (php)
IV. rethrow
Traiter partiellement puis remonter l’exception vers le haut
Rôle : exécuter une partie du traitement de récupération dans la fonction actuelle, puis transmettre l’exception à la fonction appelante pour un complément de traitement.
Parfois, on ne peut pas gérer l’erreur complètement dans la fonction courante ; il faut remonter l’exception afin que le code appelant puisse aussi intervenir dessus.
void misbehave() {
try {
dynamic foo = true;
print(foo++); // true ne supporte pas l'incrémentation, erreur à l'exécution
} catch (e) {
print("Traitement local dans misbehave : ${e.runtimeType}");
rethrow; // Relancer l'exception pour le try externe
}
}
void main() {
try {
misbehave();
} catch (e) {
print("Traitement final dans main : ${e.runtimeType}");
}
}
Langage du code : Dart (dart)
Déroulement de l’exécution :
Traitement local dans misbehave : NoSuchMethodError
Traitement final dans main : NoSuchMethodError
Langage du code : PHP (php)
Ici, l’erreur est traitée à la fois dans la fonction misbehave et dans main.
V. Bloc finally
S’exécute systématiquement, erreur ou pas
Deux cas d’usage principaux :
- Seul try + finally : L’exception n’est pas interceptée ; le programme plante après l’exécution du finally.
- try + catch + finally : Traiter d’abord l’erreur, puis exécuter finally (réservé à la libération des ressources).
1 : try + finally
void cleanLlamaStalls() => print("Nettoyer les ressources, bloc garanti d'exécution");
void breedMoreLlamas() => throw Exception("Une erreur est survenue");
void main() {
try {
breedMoreLlamas();
} finally {
cleanLlamaStalls();
}
}
Langage du code : Dart (dart)
Le code de nettoyage s’exécute, mais l’exception non interceptée fait planter le programme à la fin.
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Nettoyer les ressources, bloc garanti d'exécution
Unhandled exception:
Exception: Une erreur est survenue
#0 breedMoreLlamas (file:///D:/dartdemo/firstdart/bin/firstdart.dart:2:27)
#1 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:5)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#3 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Langage du code : HTML, XML (xml)
2 : try + catch + finally
Syntaxe standard pour libérer des ressources, par exemple fermer un fichier ouvert
void cleanLlamaStalls() => print("Fermer les fichiers / libérer les ressources système");
void breedMoreLlamas() => throw FormatException("Échec de l'analyse");
void main() {
try {
breedMoreLlamas();
} catch (e) {
print("Exception interceptée : $e");
} finally {
cleanLlamaStalls();
}
}
Langage du code : Dart (dart)
Ordre d’exécution : levée de l’exception → traitement dans catch → exécution du finally
Résultat de l’exécution
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Exception interceptée : FormatException: Échec de l'analyse
Fermer les fichiers / libérer les ressources système
Langage du code : PHP (php)
VI. assert : assertions
Ne fonctionne qu’en développement/débogage, totalement inactivé en production
assert(conditionBooléenne, [messageErreurFacultatif])
Lève une AssertionError si la condition vaut false ; ignoré complètement en version production, sans surcoût de performance.
1 : Exemple d’assertion basique
void main() {
String? text;
int number = 120;
String url = "http://foxdevelop.com";
assert(text != null); // Vérifier que la variable n'est pas nulle
assert(number < 100); // Contrôler la plage numérique
assert(url.startsWith("https")); // Vérifier le protocole de l'URL
}
Langage du code : JavaScript (javascript)
L’exécution de ce code n’affiche absolument rien par défaut !
Les assertions sont désactivées par défaut ; il faut activer un paramètre de lancement pour les utiliser, voir ci-dessous.
2 : Message d’erreur personnalisé pour une assertion échouée
void main() {
String url = "http://test.com";
assert(
url.startsWith("https"),
"L'adresse $url doit commencer par https",
);
}
Langage du code : JavaScript (javascript)
On peut définir librement le message affiché quand une assertion échoue.
Comment activer les assertions
- Mode Debug Flutter : assertions activées par défaut
- Lancement via commande dart :
dart --enable-asserts nom-du-fichier.dart - Compilation pour la production : tout le code des assertions est supprimé, sans perte de performance
D:\dartdemo\firstdart\bin>dart --enable-asserts firstdart.dart
Unhandled exception:
'file:///D:/dartdemo/firstdart/bin/firstdart.dart': Failed assertion: line 6 pos 10: 'text != null': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:10)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Langage du code : PHP (php)
dart run et la commande simple dart désactivent les assertions par défaut, il faut ajouter le drapeau --enable-asserts :
Exemple de commande de lancement
dart run --enable-asserts main.dartLangage du code : CSS (css)
Si votre terminal se trouve déjà à la racine du projet, utilisez cette version abrégée :
Commande de lancement :
dart run --enable-asserts
dart run: Exécuter directement le code source Dart, adapté aux tests de développement
dart nom-fichier: Syntaxe simplifiée pour lancer un seul fichier
dart compile exe: Compiler un exécutable autonome, les assertions sont toujours désactivées dans le binaire compilé
Les fichiers Dart se trouvent dans le dossier bin du projet. Vous pouvez naviguer dans bin pour lancer le fichier directement, ou remonter à la racine du projet pour exécuter l’ensemble du projet.
dart run –enable-asserts
Voici les deux méthodes : exécution depuis le dossier bin, et exécution depuis la racine parent du projet.
D:\dartdemo\firstdart\bin>dart --enable-asserts firstdart.dart
Unhandled exception:
'file:///D:/dartdemo/firstdart/bin/firstdart.dart': Failed assertion: line 6 pos 10: 'text != null': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:10)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)
D:\dartdemo\firstdart\bin>dart run
Building package executable...
Built firstdart:firstdart.
D:\dartdemo\firstdart\bin>cd ..
D:\dartdemo\firstdart>dart run --enable-asserts
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
'file:///D:/dartdemo/firstdart/bin/firstdart.dart': Failed assertion: line 6 pos 10: 'text != null': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:10)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Langage du code : PHP (php)
Aucune exception ne sera levée si la condition de l’assertion vaut true
Modifier l’exemple : remplacer http par https sur l’URL, passer text != null à text == null, mettre number à 99
void main() {
String? text;
int number = 99;
String url = "https://foxdevelop.com";
assert(text == null); // Vérifier la nullité
assert(number < 100); // Contrôler la plage numérique
assert(url.startsWith("https")); // Vérifier le protocole de l'URL
}Langage du code : Dart (dart)
Une nouvelle exécution ne produit aucune erreur
D:\dartdemo\firstdart>dart run --enable-asserts
Building package executable...
Built firstdart:firstdart.Langage du code : CSS (css)
VII. Exemple complet
void cleanResource() => print("finally : libérer les ressources occupées");
void testError() {
try {
int num = 150;
assert(num < 100, "Le nombre doit être inférieur à 100");
throw FormatException("Format de données invalide");
} on FormatException catch (e) {
print("Exception de format interceptée : $e");
rethrow;
} finally {
cleanResource();
}
}
void main() {
try {
testError();
} catch (e) {
print("main intercepte l'exception relancée : $e");
}
}
Langage du code : PHP (php)
Résultat de l’exécution
D:\dartdemo\firstdart>dart run --enable-asserts
Building package executable...
Built firstdart:firstdart.
finally : libérer les ressources occupées
main intercepte l'exception relancée : 'file:///D:/dartdemo/firstdart/bin/firstdart.dart':
Failed assertion: line 6 pos 12: 'num < 100': Le nombre doit être inférieur à 100Langage du code : PHP (php)
Démonstration complète du traitement des exceptions et erreurs