Menu
CoddyTech

使用 try 捕获错误

本课属于 Coddy Flutter 学习旅程的“数据与网络”单元。第 10 课,共 27 课。

网络调用可能会失败:手机没有信号、服务器宕机,或者路径错误。fetch 失败时,会抛出一个错误:一个 ApiException,它是在 api.dart 顶部定义的小类,包含 statusCode 和 message。如果没有捕获错误,函数就会停止运行,控制台会显示红色错误,而用户会一直看到转不停的加载图标。

用 try 和 catch 捕获错误:

try {
  final text = await fetch('/message');
  // 只有 fetch 成功时才会运行
} catch (e) {
  // 只有 fetch 抛出异常时才会运行
  print('It failed: $e');
}

Dart 会运行 try 代码块。如果其中任何内容抛出错误,Dart 会直接跳到 catch,并将错误存入 e。try 中出错行之后的代码都不会运行。

把 await 本身放在 try 里面:抛出错误的就是这一行。然后用文字告诉用户发生了什么,而不是让程序崩溃。

要在预览中查看失败效果,请在 main 的第一行写入 offline = true;,然后按“运行”。offline 来自 api.dart:它会让每次调用都失败,就像手机没有信号一样。按“检查”前,请删除这一行。

challenge icon

挑战

中等

让 loadMessage 在调用失败时也能正常处理:

  • 把 fetch 和它后面的 setState 放进 try 代码块中
  • 在 catch (e) 中,停止加载动画,并将消息设置为 Could not load: $e

亲手试试

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 icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

数据与网络中的所有课

自己练习: Flutter 在线编译器