Menu
CoddyTech

Déclencher une erreur

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

Les erreurs ne concernent pas uniquement les serveurs. Vos propres fonctions peuvent refuser de continuer. Lorsqu’une fonction reçoit quelque chose qu’elle ne peut pas traiter, elle lève une exception :

Future<void> saveName(String name) async {
  if (name.isEmpty) {
    throw Exception('The name cannot be empty');
  }
  // enregistrer le nom
}

throw arrête la fonction à cet endroit, comme return, mais renvoie une erreur au lieu d’une valeur. Exception('...') est l’erreur, accompagnée d’un message qui indique ce qui s’est mal passé.

La personne qui a appelé la fonction l’intercepte avec try et catch, exactement comme une erreur de fetch. Convertie en texte, une Exception commence par Exception: , suivie de votre message.

C’est aussi ainsi que fonctionne un véritable fetch. Chaque réponse d’un serveur est accompagnée d’un code d’état : 200 signifie OK, 404 signifie introuvable. Lorsque le code n’est pas 200, votre code lève une exception, afin que l’écran n’affiche jamais une réponse incorrecte comme s’il s’agissait de données :

final response = await http.get(Uri.parse(url));
if (response.statusCode != 200) {
  throw Exception('The server answered ${response.statusCode}');
}
return response.body;
challenge icon

Défi

Facile

Appuie sur Save alors que le champ est vide : le message Saved: s’affiche sans nom. Fais en sorte que saveName refuse un nom vide : après l’attente, si name est vide, lance Exception('The name cannot be empty'). La fonction save intercepte déjà l’exception et affiche le message.

Essayez vous-même

import 'package:flutter/material.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: NameScreen(),
    );
  }
}

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

  @override
  State<NameScreen> createState() => _NameScreenState();
}

class _NameScreenState extends State<NameScreen> {
  final controller = TextEditingController();
  String status = '';

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  Future<void> saveName(String name) async {
    await Future.delayed(const Duration(seconds: 1));
  }

  Future<void> save() async {
    try {
      await saveName(controller.text);
      setState(() {
        status = 'Saved: ${controller.text}';
      });
    } catch (e) {
      setState(() {
        status = '$e';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: controller,
              decoration: const InputDecoration(labelText: 'Name'),
            ),
            const SizedBox(height: 16),
            ElevatedButton(onPressed: save, child: const Text('Save')),
            const SizedBox(height: 16),
            Text(status, style: const TextStyle(fontSize: 18)),
          ],
        ),
      ),
    );
  }
}
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