ليركسالمدونة
المقالاتسجل التحديثاتالتحديثاتالتوثيق
English
لوحة التحكم
ليركس

مدونة ليركس: أدلة لمطوري التطبيقات، وأخبار كل إصدار من ليركس وحزم SDK.

المدونة

المقالاتسجل التحديثات خلاصة RSS

ليركس

الرئيسيةالأسعارالتوثيقسياسة الاسترداد

© 2026 ليركس · جميع الحقوق محفوظة

ليركسالمدونة
المقالاتسجل التحديثاتالتحديثاتالتوثيق
English
لوحة التحكم
  1. مدونة ليركس
fluttercrash reportinggetting started

تتبّع أعطال تطبيقات Flutter: دليل عملي للإعداد

معظم المستخدمين لا يبلّغون عن الأعطال، بل يغادرون. أعدّ تتبّع الأعطال في تطبيق Flutter خلال دقائق: ما الذي يُلتقط، وكيف تضيف السياق، وكيف تتخلص من الضجيج.

فريق ليركس

30 أكتوبر 20265 دقائق قراءة

شاشة دفع في تطبيق Flutter تتعطل، ومسار الاستدعاء، والمشكلة المجمّعة في لوحة تحكم ليركس
محتويات المقال
  1. 1. أضِف الحزمة
  2. 2. شغّلها في main()

اقرأ أيضًا

مستخدم واحد في المنتصف يصله الإشعار نفسه على آيفون وهاتف أندرويد ومتصفح كروم وجهاز ماك
pushEN

أرسل الإشعار إلى شخص، لا إلى جهاز

لدى مستخدمك هاتف وحاسوب وتبويب في المتصفح. توقّف عن تخزين رموز الأجهزة: اربط الأجهزة بمعرّف المستخدم في نظامك وأرسل مرة واحدة إلى iOS وأندرويد والويب وmacOS.

30 أكتوبر 20265 دقائق قراءة

شاشة 'تحديث مطلوب' وإعدادات التحكم بالإصدارات وشاشة صيانة 'نعود قريباً'
release controlEN

افرض تحديث التطبيق أو فعّل وضع الصيانة دون نشر إصدار جديد

إصدار قديم يتعطل مع الـ API الجديدة، أو الخادم يحتاج ساعة صيانة. اضبط قواعد التحديث ونوافذ الصيانة من لوحة التحكم وستلتزم بها كل التطبيقات خلال دقائق.

ليركس

مدونة ليركس: أدلة لمطوري التطبيقات، وأخبار كل إصدار من ليركس وحزم SDK.

المدونة

المقالاتسجل التحديثات خلاصة RSS

ليركس

الرئيسيةالأسعارالتوثيقسياسة الاسترداد

© 2026 ليركس · جميع الحقوق محفوظة

  • 3. ما الذي يُلتقط تلقائياً
  • 4. أرسِل الأخطاء التي تعالجها
  • 5. اعرف من تأثّر
  • 6. تخلّص من الضجيج قبل أن يصلك
  • 7. ‏Flutter Web يحتاج خطوة إضافية
  • 8. ما الذي تراه في لوحة التحكم
  • قائمة مراجعة
  • معظم من يواجه عطلاً في تطبيقك لن يخبرك به. يغلق التطبيق ويحاول مرة أخرى، وإذا تكرر العطل يحذفه أو يترك تقييماً بنجمة واحدة يقول "لا يعمل". وحين يصلك الخبر يكون الخلل قد بقي أياماً بين يدي المستخدمين.

    تتبّع الأعطال يقلب هذه المعادلة: كل خطأ لم يُعالَج يصلك مع مسار الاستدعاء (stack trace) والجهاز ورقم الإصدار، ومجمّعاً بحيث يظهر الخلل الذي تكرر عشرة آلاف مرة كمشكلة واحدة. يشرح هذا الدليل إعداده في تطبيق Flutter بحزمة lerix_flutter، وما الذي يُلتقط تلقائياً وما الذي لا يُلتقط، وكيف تحافظ على تقارير مفيدة.

    1. أضِف الحزمة

    أضِف lerix_flutter إلى ملف pubspec.yaml ثم نزّلها:

    dependencies:
      lerix_flutter: ^0.7.0
    
    flutter pub get
    

    تتبّع الأعطال يحتاج هذه الحزمة وحدها. الإشعارات (lerix_messaging) والتحديث داخل التطبيق من Google Play (lerix_app_update) حزمتان منفصلتان، فلا تحمل التطبيقات التي لا تستخدمهما شيفرتهما. وإذا أضفتهما لاحقاً فاجعل الحزم الثلاث على الإصدار نفسه.

    تعمل الحزمة على أندرويد وiOS وmacOS وWindows والويب.

    2. شغّلها في main()

    أنشئ مشروعاً في لوحة تحكم ليركس وانسخ مفتاح الـ API والاسم المختصر (slug) من إعدادات المشروع. ثم مرّر استدعاء runApp إلى Lerix.init:

    import 'package:flutter/material.dart';
    import 'package:lerix_flutter/lerix_flutter.dart';
    
    void main() {
      Lerix.init(
        url: 'https://api.lerix.dev/v1/your-project-slug',
        apiKey: 'your-api-key',
        projectId: 'your-project-slug',
        builder: () => runApp(const MyApp()),
      );
    }
    

    تفصيلتان توفّران عليك الوقت:

    • projectId هو الاسم المختصر للمشروع، أي الاسم القصير الظاهر في رابط لوحة التحكم، وليس المعرّف الطويل.
    • لا تحتاج إلى runZonedGuarded. تتولى Lerix.init إعداد منطقة الأخطاء (zone) وWidgetsFlutterBinding بنفسها ثم تستدعي builder. وإذا فشل الإعداد (لعدم وجود اتصال عند أول تشغيل مثلاً) يعمل تطبيقك كالمعتاد.

    3. ما الذي يُلتقط تلقائياً

    بعد تشغيل init تُرسَل ثلاثة أنواع من الأخطاء غير المعالَجة كأعطال، على كل المنصات بما فيها Flutter Web:

    • أخطاء إطار العمل عبر FlutterError.onError: أخطاء البناء والتخطيط والرسم. وتبقى مطبوعة في وحدة التحكم في نسخ التطوير، فلا يتغير شيء في طريقة عملك.
    • الأخطاء خارج إطار العمل عبر PlatformDispatcher.onError، مثل استثناء داخل دالة async لم ينتظرها أحد.
    • الأخطاء في منطقة التطبيق التي تفلت من كل ما سبق.

    يحمل كل تقرير طراز الجهاز ونظام التشغيل وإصداره ومعمارية المعالج والمنطقة الزمنية والدولة ورقم إصدار تطبيقك ورقم البناء، وتُقرأ من التطبيق نفسه. ويحمل أيضاً معرّف الجلسة الحالية، وبه تعرض لوحة التحكم نسبة الجلسات والمستخدمين الخالين من الأعطال لكل إصدار.

    انتبه للحدود: الأخطاء داخل isolate آخر، والأعطال في شيفرة Kotlin أو Swift الأصلية، لا تُلتقط تلقائياً. ضع عمل الـ isolate داخل try/catch وأرسل الخطأ بنفسك (القسم التالي).

    4. أرسِل الأخطاء التي تعالجها

    الاستثناء الذي تلتقطه بنفسك كثيراً ما يكون الأفيد، لأنك تعرف ماذا كان المستخدم يفعل. أرسِله بـ Lerix.throwError وأرفق ما يساعدك على إعادة إنتاجه:

    try {
      await payments.charge(cart);
    } catch (e, stack) {
      await Lerix.throwError(
        e,
        stack,
        bugSeverity: BugSeverity.high,
        metaData: {
          'cartItems': cart.items.length,
          'paymentMethod': 'card',
        },
      );
      showPaymentFailed();
    }
    

    لا ترمي throwError أي استثناء: إذا تعذّر الإرسال يُسجَّل ذلك ويستمر تطبيقك. ودرجة الخطورة إحدى: critical أو high أو medium أو low، ويمكنك تحديد نوع الخطأ bugType مثل BugType.networkError أو BugType.validationError لتصفّي به لاحقاً.

    5. اعرف من تأثّر

    "واجه هذا الخطأ 312 مستخدماً" أولويته غير "واجهه مختبِر واحد". أخبر ليركس بالمستخدم الذي سجّل دخوله، وامسحه عند الخروج:

    // بعد تسجيل الدخول
    await Lerix.setUser(user.id);
    
    // عند تسجيل الخروج
    await Lerix.clearUser();
    

    استخدم معرّف المستخدم الثابت في نظامك، لا البريد ولا رقم الهاتف. عندها يرتبط كل تقرير من ذلك الجهاز بالشخص، والمعرّف نفسه يتيح لك لاحقاً إرسال إشعار إليه على كل أجهزته.

    6. تخلّص من الضجيج قبل أن يصلك

    بعض الأخطاء لا تستحق تنبيهاً: انقطاع اتصال في القطار، أو حزمة خارجية تسجّل خطأً بدل أن تفشل. خياران في Lerix.init يعالجان ذلك على الجهاز نفسه:

    Lerix.init(
      url: 'https://api.lerix.dev/v1/your-project-slug',
      apiKey: 'your-api-key',
      projectId: 'your-project-slug',
      ignoreErrors: [
        'SocketException',                // "يحتوي" دون تمييز حالة الأحرف
        RegExp(r'^HttpException: 40[13]'),
      ],
      beforeSend: (event) {
        // تجاهل تقارير الاختبارات الخاصة بك
        if (event.metadata?['test'] == true) return null;
        // احذف أي رمز دخول وصل إلى نص الرسالة
        return event.copyWith(
          message: event.message.replaceAll(RegExp(r'token=\S+'), 'token=***'),
        );
      },
      builder: () => runApp(const MyApp()),
    );
    

    يعمل ignoreErrors أولاً ثم beforeSend. والنص الذي تطابق عليه هو عنوان المشكلة، ويتضمن اسم صنف الخطأ. إرجاع null من beforeSend يُسقط التقرير بصمت. وإذا رمت دالة beforeSend نفسها استثناءً يُرسَل التقرير الأصلي، فلا يُخفي خلل في المرشّح عطلاً حقيقياً.

    ويضيف الخادم بعض القواعد من عنده. مثلاً رسالة Flutter المعروفة A RenderFlex overflowed by… تبقى مسجّلة، لكن كخلل واجهة منخفض الخطورة بدل عطل حرج.

    7. ‏Flutter Web يحتاج خطوة إضافية

    نسخ الإصدار من Flutter Web مصغّرة (minified)، فيبدو مسار الاستدعاء هكذا: main.dart.js:1:48213. ابنِ التطبيق بالخيار --source-maps وارفع الخرائط بعد كل بناء، ويشرح دليل خرائط المصدر ذلك خطوة بخطوة. أما نسخ أندرويد وiOS فلا تحتاج أي إعداد إضافي.

    8. ما الذي تراه في لوحة التحكم

    لا تصلك التقارير كسيل من النسخ المكررة. يجمعها ليركس في مشكلات حسب السطر الأول من الرسالة (بعد إخفاء الأرقام والمعرّفات والبريد والروابط) وأول إطار في مسار الاستدعاء من شيفرتك أنت، دون النظر إلى أرقام الأسطر. فرسالتا Order 1234 not found وOrder 5678 not found من الدالة نفسها مشكلة واحدة.

    تعرض كل مشكلة عدد مرات حدوثها، والمستخدمين المتأثرين، وأول ظهور وآخر ظهور، ومسار الاستدعاء كاملاً مع تفاصيل الجهاز والتطبيق. ومن هناك يمكنك أن:

    • تسندها إلى زميل وتدوّن ملاحظاتك عليها.
    • تحلّها. وإذا عاد الخطأ نفسه في إصدار لاحق تُفتح المشكلة من جديد تلقائياً وتصلك رسالة بريد، فلا يمرّ خلل عائد دون أن تلاحظه.
    • تتجاهلها. يستمر العدّ لكن تتوقف التنبيهات.
    • تقرأ ملخّص الذكاء الاصطناعي لما حدث، وتفتح منه مشكلة في GitHub إذا كان مستودعك مربوطاً.

    قائمة مراجعة

    1. ‏lerix_flutter: ^0.7.0 في pubspec.yaml.
    2. ‏Lerix.init في main() بمفتاح الـ API والاسم المختصر للمشروع، وrunApp داخل builder.
    3. ‏Lerix.throwError في كتل catch المهمة.
    4. ‏Lerix.setUser بعد الدخول وLerix.clearUser عند الخروج.
    5. ‏ignoreErrors وbeforeSend للضجيج الذي تعرفه مسبقاً.
    6. خرائط المصدر لـ Flutter Web.

    ثم أوقِع التطبيق عمداً مرة واحدة بزر يرمي خطأً، وتأكد أنه ظهر في لوحة التحكم. يستغرق ذلك خمس دقائق، وهو الطريقة الوحيدة لتطمئن أن العطل الحقيقي القادم سيصلك.

    fluttercrash reportinggetting started
    شارك المقال X LinkedIn

    محتويات المقال

    1. 1. أضِف الحزمة
    2. 2. شغّلها في main()
    3. 3. ما الذي يُلتقط تلقائياً
    4. 4. أرسِل الأخطاء التي تعالجها
    5. 5. اعرف من تأثّر
    6. 6. تخلّص من الضجيج قبل أن يصلك
    7. 7. ‏Flutter Web يحتاج خطوة إضافية
    8. 8. ما الذي تراه في لوحة التحكم
    9. قائمة مراجعة

    30 أكتوبر 20266 دقائق قراءة

    مسار استدعاء مصغّر بجانب الخطأ نفسه بعد ردّه إلى شيفرة TypeScript الأصلية
    source mapsEN

    مسارات استدعاء مقروءة من JavaScript المصغّر: خرائط المصدر وتجميع الأخطاء

    السطر index-8f3a1c.js:1:48213 لا يخبرك بشيء. ارفع خرائط المصدر من البناء ليشير كل خطأ إلى ملفك وسطرك ودالتك، وتعرّف على طريقة تجميع الأخطاء في مشكلات.

    30 أكتوبر 20266 دقائق قراءة

    اكتشف العطل القادم قبل أن يبلّغك عنه المستخدمون

    تتبّع الأعطال والإشعارات والتحليلات ومساعد ذكاء اصطناعي يقرأ شيفرتك. ابدأ مجانًا.

    ابدأ مجانًا