Menu
CoddyTech
flag Ar iconالعربيةdown icon

التقاط الأخطاء باستخدام try

جزء من قسم البيانات والشبكة في رحلة Flutter على Coddy. الدرس 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: فهذا هو السطر الذي يرمي الخطأ. ثم أخبر المستخدم بما حدث، بكلمات واضحة، بدلًا من أن يتعطل البرنامج.

لمشاهدة الفشل في المعاينة، اكتب offline = true; كسطر أول في main واضغط على 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 عبر الإنترنت