Menu
CoddyTech

Intercepter les erreurs avec try

Fait partie de la section Données et réseau du Journey Flutter de Coddy. Leçon 10 sur 27.

Un appel réseau peut échouer : le téléphone n’a pas de signal, le serveur est hors service, le chemin est incorrect. Lorsque fetch échoue, il lève une erreur : une ApiException, une petite classe en haut de api.dart avec un statusCode et un message. Une erreur que personne n’intercepte interrompt votre fonction et s’affiche en rouge dans la Console, tandis que la personne voit un indicateur de chargement qui ne s’arrête jamais.

Interceptez-la avec try et catch :

try {
  final text = await fetch('/message');
  // ne s’exécute que lorsque fetch a réussi
} catch (e) {
  // ne s’exécute que lorsque fetch a levé une exception
  print('It failed: $e');
}

Dart exécute le bloc try. Si une instruction de ce bloc lève une erreur, Dart passe directement à catch, et e contient l’erreur. Les lignes qui suivent celle qui a échoué dans try ne sont jamais exécutées.

Placez le await lui-même dans try : c’est cette ligne qui lève l’erreur. Expliquez ensuite à la personne ce qui s’est passé, avec des mots, au lieu de provoquer un plantage.

Pour voir l’échec dans l’aperçu, écrivez offline = true; comme première ligne de main, puis appuyez sur Run. offline provient de api.dart : il fait échouer chaque appel comme si le téléphone n’avait pas de signal. Supprimez cette ligne avant d’appuyer sur Check.

challenge icon

Défi

Moyen

Fais en sorte que loadMessage survive à un échec de l’appel :

  • place fetch et le setState qui le suit dans un bloc try
  • dans catch (e), arrête le spinner et définis le message sur Could not load: $e

Essayez vous-même

import 'package:flutter/material.dart';

import 'api.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MessageScreen(),
    );
  }
}

class MessageScreen extends StatefulWidget {
  const MessageScreen({super.key});

  @override
  State<MessageScreen> createState() => _MessageScreenState();
}

class _MessageScreenState extends State<MessageScreen> {
  String message = 'No message yet';
  bool loading = false;

  Future<void> loadMessage() async {
    setState(() {
      loading = true;
    });
    final text = await fetch('/message');
    setState(() {
      message = text;
      loading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            loading
                ? const CircularProgressIndicator()
                : Text(message, style: const TextStyle(fontSize: 24)),
            const SizedBox(height: 24),
            ElevatedButton(onPressed: loadMessage, child: const Text('Load message')),
          ],
        ),
      ),
    );
  }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Données et réseau

Entraînez-vous par vous-même : Compilateur Flutter en ligne