Menu
CoddyTech

try로 오류 잡기

Coddy Flutter 여정의 데이터와 네트워크 섹션에 포함된 레슨. 27개 중 10번째.

네트워크 호출은 실패할 수 있습니다. 휴대전화에 신호가 없거나, 서버가 다운되었거나, 경로가 잘못되었을 수 있습니다. fetch가 실패하면 오류를 발생시킵니다. 즉, api.dart 맨 위에 있는 작은 클래스인 ApiException을 발생시키며, 이 클래스에는 statusCode와 message가 있습니다. 아무도 잡지 않는 오류는 함수를 중단시키고 Console에 빨간 오류로 표시되며, 사용자는 끝나지 않는 로딩 표시만 보게 됩니다.

try와 catch로 오류를 잡으세요.

try {
  final text = await fetch('/message');
  // fetch가 성공했을 때만 실행됩니다
} catch (e) {
  // fetch가 예외를 던졌을 때만 실행됩니다
  print('It failed: $e');
}

Dart는 try 블록을 실행합니다. 그 안에서 무엇이든 오류를 발생시키면 Dart는 곧바로 catch로 이동하고, e에 오류가 담깁니다. try에서 오류가 발생한 줄 뒤에 있는 코드는 실행되지 않습니다.

오류를 발생시키는 줄은 await 자체이므로, await를 try 안에 넣으세요. 그런 다음 앱이 중단되는 대신 무슨 일이 일어났는지 사용자에게 말로 알려 주세요.

미리 보기에서 실패하는 것을 확인하려면 main의 첫 번째 줄에 offline = true;를 작성하고 Run을 누르세요. offline은 api.dart에 있습니다. 이 값은 휴대전화에 신호가 없는 것처럼 모든 호출을 실패하게 합니다. Check를 누르기 전에 이 줄을 삭제하세요.

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 컴파일러