Menu
CoddyTech

Przechwytywanie błędów za pomocą try

Część sekcji Dane i sieć ścieżki Flutter w Coddy. Lekcja 10 z 27.

Połączenie sieciowe może się nie powieść: telefon nie ma zasięgu, serwer nie działa albo ścieżka jest nieprawidłowa. Gdy fetch się nie powiedzie, zgłasza błąd: ApiException, czyli małą klasę na początku pliku api.dart, zawierającą statusCode i message. Błąd, którego nikt nie przechwytuje, przerywa działanie funkcji i pojawia się w konsoli jako czerwony komunikat o błędzie, a użytkownik widzi kręcące się kółko, które nigdy nie znika.

Przechwyć go za pomocą try i catch:

try {
  final text = await fetch('/message');
  // wykonuje się tylko wtedy, gdy fetch się powiodło
} catch (e) {
  // wykonuje się tylko wtedy, gdy fetch zgłosiło wyjątek
  print('It failed: $e');
}

Dart wykonuje blok try. Jeśli cokolwiek w nim zgłosi błąd, Dart natychmiast przechodzi do catch, a e zawiera błąd. Wiersze po tym, który spowodował błąd w bloku try, nigdy nie zostaną wykonane.

Umieść samo await wewnątrz try: to właśnie ten wiersz zgłasza błąd. Następnie wyjaśnij użytkownikowi, co się stało, zamiast doprowadzać do awarii.

Aby zobaczyć błąd w podglądzie, wpisz offline = true; jako pierwszy wiersz funkcji main i naciśnij Run. offline pochodzi z api.dart: sprawia, że każde połączenie kończy się niepowodzeniem, tak jakby telefon nie miał zasięgu. Usuń ten wiersz, zanim naciśniesz Check.

challenge icon

Wyzwanie

Średni

Spraw, aby loadMessage działało mimo nieudanego wywołania:

  • umieść fetch i następujące po nim setState w bloku try
  • w catch (e) zatrzymaj wskaźnik ładowania i ustaw wiadomość na Could not load: $e

Spróbuj swoich sił

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 iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Dane i sieć

Poćwicz samodzielnie: Kompilator Flutter online