En aquest tema, aprendrem com gestionar errors de xarxa en aplicacions Flutter. La gestió adequada dels errors és crucial per proporcionar una experiència d'usuari fluida i professional. Veurem com detectar i manejar diferents tipus d'errors que poden ocórrer durant les sol·licituds de xarxa.

Conceptes Clau

  1. Tipus d'Errors de Xarxa:

    • Errors de Connexió
    • Errors de Temps d'Espera (Timeout)
    • Errors de Resposta (4xx, 5xx)
    • Errors de Deserialització
  2. Gestió d'Errors amb try-catch:

    • Ús de blocs try-catch per capturar excepcions.
    • Diferents tipus d'excepcions que poden ser capturades.
  3. Ús de la Llibreria http:

    • Com fer sol·licituds HTTP amb la llibreria http.
    • Com gestionar errors específics de la llibreria http.
  4. Retroalimentació a l'Usuari:

    • Mostrar missatges d'error a l'usuari.
    • Estratègies per a la recuperació d'errors.

Exemples Pràctics

Exemple 1: Captura d'Errors de Connexió

import 'package:http/http.dart' as http;

Future<void> fetchData() async {
  final url = 'https://api.example.com/data';

  try {
    final response = await http.get(Uri.parse(url));

    if (response.statusCode == 200) {
      // Processar la resposta
      print('Dades rebudes: ${response.body}');
    } else {
      // Gestionar errors de resposta
      print('Error de resposta: ${response.statusCode}');
    }
  } on http.ClientException catch (e) {
    // Gestionar errors de connexió
    print('Error de connexió: $e');
  } catch (e) {
    // Gestionar altres tipus d'errors
    print('Error inesperat: $e');
  }
}

Exemple 2: Gestió de Temps d'Espera

import 'package:http/http.dart' as http;

Future<void> fetchDataWithTimeout() async {
  final url = 'https://api.example.com/data';

  try {
    final response = await http.get(Uri.parse(url)).timeout(Duration(seconds: 5));

    if (response.statusCode == 200) {
      // Processar la resposta
      print('Dades rebudes: ${response.body}');
    } else {
      // Gestionar errors de resposta
      print('Error de resposta: ${response.statusCode}');
    }
  } on http.ClientException catch (e) {
    // Gestionar errors de connexió
    print('Error de connexió: $e');
  } on TimeoutException catch (e) {
    // Gestionar errors de temps d'espera
    print('Error de temps d\'espera: $e');
  } catch (e) {
    // Gestionar altres tipus d'errors
    print('Error inesperat: $e');
  }
}

Exemple 3: Mostrar Missatges d'Error a l'Usuari

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Gestió d\'Errors de Xarxa')),
        body: Center(
          child: ElevatedButton(
            onPressed: () => fetchData(context),
            child: Text('Obtenir Dades'),
          ),
        ),
      ),
    );
  }

  Future<void> fetchData(BuildContext context) async {
    final url = 'https://api.example.com/data';

    try {
      final response = await http.get(Uri.parse(url));

      if (response.statusCode == 200) {
        // Processar la resposta
        print('Dades rebudes: ${response.body}');
      } else {
        // Mostrar missatge d'error a l'usuari
        _showErrorDialog(context, 'Error de resposta: ${response.statusCode}');
      }
    } on http.ClientException catch (e) {
      // Mostrar missatge d'error a l'usuari
      _showErrorDialog(context, 'Error de connexió: $e');
    } catch (e) {
      // Mostrar missatge d'error a l'usuari
      _showErrorDialog(context, 'Error inesperat: $e');
    }
  }

  void _showErrorDialog(BuildContext context, String message) {
    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text('Error'),
          content: Text(message),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: Text('D\'acord'),
            ),
          ],
        );
      },
    );
  }
}

void main() => runApp(MyApp());

Exercicis Pràctics

Exercici 1: Captura d'Errors de Xarxa

Descripció: Escriu una funció que faci una sol·licitud HTTP a una URL i gestioni els errors de connexió, temps d'espera i resposta. Mostra un missatge d'error adequat per a cada tipus d'error.

Solució:

import 'package:http/http.dart' as http;
import 'dart:async';

Future<void> fetchData() async {
  final url = 'https://api.example.com/data';

  try {
    final response = await http.get(Uri.parse(url)).timeout(Duration(seconds: 5));

    if (response.statusCode == 200) {
      // Processar la resposta
      print('Dades rebudes: ${response.body}');
    } else {
      // Gestionar errors de resposta
      print('Error de resposta: ${response.statusCode}');
    }
  } on http.ClientException catch (e) {
    // Gestionar errors de connexió
    print('Error de connexió: $e');
  } on TimeoutException catch (e) {
    // Gestionar errors de temps d'espera
    print('Error de temps d\'espera: $e');
  } catch (e) {
    // Gestionar altres tipus d'errors
    print('Error inesperat: $e');
  }
}

Exercici 2: Mostrar Missatges d'Error a l'Usuari

Descripció: Modifica l'exemple anterior per mostrar missatges d'error a l'usuari mitjançant un AlertDialog.

Solució:

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Gestió d\'Errors de Xarxa')),
        body: Center(
          child: ElevatedButton(
            onPressed: () => fetchData(context),
            child: Text('Obtenir Dades'),
          ),
        ),
      ),
    );
  }

  Future<void> fetchData(BuildContext context) async {
    final url = 'https://api.example.com/data';

    try {
      final response = await http.get(Uri.parse(url)).timeout(Duration(seconds: 5));

      if (response.statusCode == 200) {
        // Processar la resposta
        print('Dades rebudes: ${response.body}');
      } else {
        // Mostrar missatge d'error a l'usuari
        _showErrorDialog(context, 'Error de resposta: ${response.statusCode}');
      }
    } on http.ClientException catch (e) {
      // Mostrar missatge d'error a l'usuari
      _showErrorDialog(context, 'Error de connexió: $e');
    } on TimeoutException catch (e) {
      // Mostrar missatge d'error a l'usuari
      _showErrorDialog(context, 'Error de temps d\'espera: $e');
    } catch (e) {
      // Mostrar missatge d'error a l'usuari
      _showErrorDialog(context, 'Error inesperat: $e');
    }
  }

  void _showErrorDialog(BuildContext context, String message) {
    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text('Error'),
          content: Text(message),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: Text('D\'acord'),
            ),
          ],
        );
      },
    );
  }
}

void main() => runApp(MyApp());

Conclusió

La gestió d'errors de xarxa és una part essencial del desenvolupament d'aplicacions Flutter. Hem après a capturar i gestionar diferents tipus d'errors de xarxa, així com a proporcionar retroalimentació adequada a l'usuari. Amb aquests coneixements, estàs preparat per manejar errors de xarxa de manera efectiva en les teves aplicacions Flutter.

Curs de Desenvolupament Flutter

Mòdul 1: Introducció a Flutter

Mòdul 2: Conceptes Bàsics de Programació en Dart

Mòdul 3: Widgets de Flutter

Mòdul 4: Gestió de l'Estat

Mòdul 5: Navegació i Enrutament

Mòdul 6: Xarxes i APIs

Mòdul 7: Persistència i Emmagatzematge

Mòdul 8: Conceptes Avançats de Flutter

Mòdul 9: Proves i Depuració

Mòdul 10: Desplegament i Manteniment

Mòdul 11: Flutter per a Web i Escriptori

© Copyright 2024. Tots els drets reservats