Menu
CoddyTech

Gestire gli errori con try

Fa parte della sezione Dati e rete del percorso Flutter di Coddy. Lezione 10 di 27.

Una chiamata di rete può non riuscire: il telefono non ha segnale, il server è inattivo, il percorso è errato. Quando fetch non riesce, genera un errore: un’ApiException, una piccola classe all’inizio di api.dart con un statusCode e un message. Un errore che nessuno intercetta interrompe la tua funzione e compare come errore rosso nella Console, mentre la persona vede un indicatore di caricamento che non si ferma mai.

Intercettalo con try e catch:

try {
  final text = await fetch('/message');
  // viene eseguito solo quando fetch è riuscito
} catch (e) {
  // viene eseguito solo quando fetch ha generato un'eccezione
  print('It failed: $e');
}

Dart esegue il blocco try. Se qualcosa al suo interno genera un errore, Dart passa direttamente a catch e e contiene l’errore. Le righe successive a quella che ha causato l’errore nel blocco try non vengono mai eseguite.

Inserisci lo stesso await dentro try: è quella la riga che genera l’errore. Poi spiega alla persona cosa è successo, a parole, invece di mandare in crash l’app.

Per vedere l’errore nell’anteprima, scrivi offline = true; come prima riga di main e premi Run. offline proviene da api.dart: fa sì che ogni chiamata non riesca, come se il telefono non avesse segnale. Rimuovi la riga prima di premere Check.

challenge icon

Sfida

Medio

Fai in modo che loadMessage gestisca una chiamata non riuscita:

  • inserisci fetch e il setState successivo in un blocco try
  • in catch (e), arresta lo spinner e imposta il messaggio su Could not load: $e

Provalo tu

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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Dati e rete

Esercitati da solo: Compilatore Flutter online