Menu
CoddyTech

Capturar errores con try

Parte de la sección Datos y red del Journey de Flutter de Coddy. Lección 10 de 27.

Una llamada de red puede fallar: el teléfono no tiene señal, el servidor está caído o la ruta es incorrecta. Cuando fetch falla, lanza un error: una ApiException, una clase pequeña al principio de api.dart con un statusCode y un message. Un error que nadie captura detiene tu función y aparece como un error rojo en la Consola, y la persona ve un indicador de carga que nunca termina.

Captúralo con try y catch:

try {
  final text = await fetch('/message');
  // solo se ejecuta cuando fetch funcionó
} catch (e) {
  // solo se ejecuta cuando fetch lanzó una excepción
  print('It failed: $e');
}

Dart ejecuta el bloque try. Si algo dentro de él lanza un error, Dart salta directamente a catch, y e contiene el error. Las líneas posteriores a la que falla dentro de try nunca se ejecutan.

Coloca el propio await dentro de try: esa es la línea que lanza el error. Después, explícale a la persona qué ocurrió con palabras, en lugar de que la aplicación se cierre inesperadamente.

Para ver cómo falla en la vista previa, escribe offline = true; como primera línea de main y pulsa Run. offline viene de api.dart: hace que todas las llamadas fallen como si el teléfono no tuviera señal. Quita esa línea antes de pulsar Check.

challenge icon

Desafío

Intermedio

Haz que loadMessage se recupere de una llamada fallida:

  • coloca fetch y el setState que va después en un bloque try
  • en catch (e), detén el indicador de carga y establece el mensaje como Could not load: $e

Pruébalo tú mismo

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 iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Datos y red

Practica por tu cuenta: Compilador de Flutter online