هل تعاني تطبيقات Flutter من الأخطاء الصامتة؟ Sentry Flutter هو الحل الأمثل!

اكتشف كيف يحل Sentry Flutter مشكلة تتبع الأخطاء ومراقبة الأداء في تطبيقاتك. دليل شامل للمطورين العرب.

المقدمة: كابوس المطورين… الأخطاء التي لا تراها!

تخيل أنك أطلقت تطبيق Flutter الجديد الخاص بك، كل شيء يبدو مثالياً في بيئة التطوير، ولكن فجأة تبدأ تقارير المستخدمين بالوصول: “التطبيق لا يعمل!”، “يحدث عطل بشكل مفاجئ!”. الأسوأ من ذلك، أنك لا تملك أي فكرة عن سبب هذه المشاكل أو مكان حدوثها. هذا هو كابوس المطورين: الأخطاء الصامتة التي تحدث في بيئة الإنتاج دون علمك، والتي تدمر تجربة المستخدم وتضر بسمعة تطبيقك. هنا يأتي دور Sentry Flutter كمنقذ حقيقي، حيث يوفر لك رؤية عميقة لكل خطأ وعطل يحدث في تطبيقك، مما يمكنك من تحديد المشكلة وإصلاحها قبل أن تتفاقم. هذا المقال هو دليلك العملي الشامل لدمج Sentry في مشاريع Flutter الخاصة بك، وتحويل الأخطاء الخفية إلى بيانات قابلة للإصلاح.

ما هو Sentry ولماذا تحتاجه في Flutter؟

Sentry هو منصة رائدة لمراقبة الأخطاء والأداء في الوقت الفعلي. إنه ليس مجرد أداة لتسجيل الأخطاء، بل هو نظام متكامل يمنحك القدرة على فهم ما يحدث داخل تطبيقك بمجرد وصوله إلى أيدي المستخدمين. بالنسبة لمطوري Flutter، يمثل Sentry Flutter إضافة لا غنى عنها، حيث يوفر SDK قويًا ومصممًا خصيصًا لالتقاط الأخطاء والاستثناءات، ومراقبة الأداء، وجمع ملاحظات المستخدمين عبر منصات متعددة (iOS، Android، Web، Desktop) .

لماذا Sentry Flutter ضروري لتطبيقك؟

  • اكتشاف الأخطاء فوراً: بدلاً من انتظار تقارير المستخدمين، يبلغك Sentry بالأخطاء لحظة وقوعها.
  • تفاصيل غنية عن الأخطاء: يوفر Sentry سياقًا كاملاً للخطأ، بما في ذلك تتبع المكدس (Stack Trace)، حالة الجهاز، إصدار التطبيق، والمزيد، مما يسهل عملية التصحيح.
  • مراقبة الأداء: لا يقتصر الأمر على الأخطاء فقط، بل يساعدك Sentry أيضًا في تحديد الاختناقات في الأداء، مثل أوقات بدء التشغيل البطيئة أو الإطارات المتجمدة.
  • تحسين تجربة المستخدم: من خلال إصلاح الأخطاء بسرعة وتحسين الأداء، تضمن تجربة أكثر سلاسة وإيجابية لمستخدميك.
  • جمع ملاحظات المستخدمين: يمكنك تمكين المستخدمين من إرسال ملاحظاتهم مباشرة عند حدوث خطأ، مما يوفر لك رؤى قيمة.

البدء مع Sentry Flutter : التثبيت والإعداد الأولي

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

1. إضافة التبعيات (Dependencies)

أولاً، قم بإضافة حزمة sentry_flutter إلى ملف pubspec.yaml الخاص بمشروعك. إذا كنت تخطط لاستخدام مكتبة Dio لإجراء طلبات HTTP، فستحتاج أيضًا إلى sentry_dio .

dependencies:
  flutter:
    sdk: flutter
  sentry_flutter: ^latest_version # تأكد من استخدام أحدث إصدار
  sentry_dio: ^latest_version   # اختياري: إذا كنت تستخدم Dio
  dio: ^latest_version          # اختياري: إذا كنت تستخدم Dio

بعد إضافة التبعيات، قم بتشغيل flutter pub get في طرفيتك.

2. تهيئة Sentry في تطبيقك

يجب تهيئة Sentry في أقرب وقت ممكن في دورة حياة تطبيقك لضمان التقاط جميع الأخطاء المحتملة. يتم ذلك عادةً في دالة main الخاصة بك. ستحتاج إلى DSN (Data Source Name) الخاص بمشروعك من لوحة تحكم Sentry .

import 'package:flutter/widgets.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await SentryFlutter.init(
    (options) {
      options.dsn = 'https://examplePublicKey@o0.ingest.sentry.io/0'; // استبدل بـ DSN الخاص بك
      options.tracesSampleRate = 1.0; // لتمكين مراقبة الأداء بنسبة 100%
      options.sendDefaultPii = true; // لإرسال معلومات تعريف شخصية افتراضية (مثل IP)
      // يمكنك إضافة المزيد من الخيارات هنا
    },
    appRunner: () => runApp(const MyApp()),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sentry Flutter Demo',
      home: Scaffold(
        appBar: AppBar(title: const Text('Sentry Demo')),
        body: Center(
          child: ElevatedButton(
            onPressed: () => throw StateError('This is a test error!'),
            child: const Text('Trigger Error'),
          ),
        ),
      ),
    );
  }
}

شرح الكود:

  • WidgetsFlutterBinding.ensureInitialized();: يضمن تهيئة Flutter قبل أي عمليات أخرى.
  • SentryFlutter.init(): هي الدالة الرئيسية لتهيئة Sentry.
    • options.dsn: مفتاح الاتصال الخاص بمشروعك في Sentry. لا تنس استبداله بـ DSN الحقيقي الخاص بك.
    • options.tracesSampleRate: يحدد نسبة العينات التي سيتم أخذها لمراقبة الأداء. القيمة 1.0 تعني 100% من العينات.
    • options.sendDefaultPii: لتمكين إرسال معلومات تعريف شخصية افتراضية (مثل عنوان IP) مع الأحداث. كن حذرًا عند تفعيل هذا الخيار وراجع سياسات الخصوصية .
  • appRunner: () => runApp(const MyApp()): يقوم بتشغيل تطبيق Flutter الخاص بك بعد تهيئة Sentry.

التقاط الأخطاء والاستثناءات

يقوم Sentry Flutter تلقائيًا بالتقاط العديد من الأخطاء، ولكن يمكنك أيضًا التقاط الأخطاء يدويًا أو تخصيص كيفية التعامل معها.

1. التقاط الأخطاء التلقائي

يقوم Sentry تلقائيًا بالتعامل مع الأخطاء التي تحدث داخل FlutterError.onError و PlatformDispatcher.onError (أو runZonedGuarded في الإصدارات الأقدم من Flutter 3.3)، مما يعني أن معظم الأخطاء غير المعالجة في واجهة المستخدم أو في منطق Dart سيتم إرسالها إلى Sentry .

2. التقاط الأخطاء يدويًا

في بعض الحالات، قد تحتاج إلى التقاط استثناءات معينة بشكل يدوي، خاصة تلك التي تعالجها كتل try-catch ولكنك لا تزال ترغب في الإبلاغ عنها إلى Sentry.

import 'package:sentry/sentry.dart';

void performRiskyOperation() {
  try {
    // عملية قد تسبب خطأ
    int result = 10 ~/ 0; // قسمة على صفر
  } catch (exception, stackTrace) {
    // التقاط الاستثناء وإرساله إلى Sentry
    Sentry.captureException(
      exception,
      stackTrace: stackTrace,
    );
    print('تم التقاط الخطأ: $exception');
  }
}

// يمكنك أيضًا إرسال رسائل بسيطة إلى Sentry
Future<void> sendCustomMessage() async {
  await Sentry.captureMessage('حدث شيء غير متوقع في دالة معينة.');
}

شرح الكود:

  • Sentry.captureException(exception, stackTrace: stackTrace);: تستخدم لإرسال استثناء معين مع تتبع المكدس الخاص به إلى Sentry.
  • Sentry.captureMessage('...');: تستخدم لإرسال رسالة نصية بسيطة إلى Sentry، والتي ستظهر كحدث في لوحة التحكم.

3. استخدام Sentry.runZonedGuarded

للحصول على تغطية شاملة للأخطاء وتتبع مسار الأحداث (Breadcrumbs) تلقائيًا، يوصى بشدة باستخدام Sentry.runZonedGuarded. هذه الدالة تغلف runZonedGuarded الأصلية في Dart وتضيف إليها وظائف Sentry .

import 'package:flutter/material.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

void main() {
  Sentry.runZonedGuarded(() async {
    WidgetsFlutterBinding.ensureInitialized();

    await SentryFlutter.init(
      (options) {
        options.dsn = 'https://examplePublicKey@o0.ingest.sentry.io/0';
        options.enablePrintBreadcrumbs = true; // لتحويل Print statements إلى Breadcrumbs
      },
      appRunner: () => runApp(const MyApp()),
    );
  }, (error, stackTrace) {
    // Sentry سيتولى التقاط الخطأ هنا تلقائيًا
    // يمكنك إضافة منطق مخصص هنا إذا لزم الأمر
    print('خطأ غير معالج تم التقاطه بواسطة runZonedGuarded: $error');
  });
}

// ... بقية كود MyApp كما هو ...

شرح الكود:

  • Sentry.runZonedGuarded(): يضمن أن أي أخطاء غير معالجة داخل هذا النطاق سيتم التقاطها بواسطة Sentry.
  • options.enablePrintBreadcrumbs = true;: خيار مفيد لتحويل جميع عبارات print() في تطبيقك إلى Breadcrumbs، مما يساعد في تتبع تسلسل الأحداث قبل وقوع الخطأ.

مراقبة الأداء (Performance Monitoring)

لا يقتصر دور Sentry على تتبع الأخطاء فحسب، بل يمتد ليشمل مراقبة أداء تطبيقك، مما يساعدك على تحديد الاختناقات وتحسين سرعة الاستجابة .

1. تتبع المعاملات (Transactions) والنطاقات (Spans)

يمكنك استخدام Sentry لتتبع أداء عمليات محددة في تطبيقك، مثل تحميل البيانات من الشبكة أو عمليات قاعدة البيانات. يتم تمثيل هذه العمليات كـ Transactions (معاملات) تحتوي على Spans (نطاقات) فرعية .

import 'package:sentry/sentry.dart';

Future<void> loadUserData() async {
  // بدء معاملة لتتبع عملية تحميل بيانات المستخدم
  final transaction = Sentry.startTransaction(
    'loadUserData',
    'data_loading',
    bindToScope: true,
  );

  try {
    // نطاق لعملية جلب البيانات من API
    final spanFetch = transaction.startChild(
      'fetch_from_api',
      description: 'Fetching user data from API',
    );
    await Future.delayed(const Duration(seconds: 2)); // محاكاة لعملية شبكة
    spanFetch.finish(status: const SpanStatus.ok());

    // نطاق لعملية معالجة البيانات
    final spanProcess = transaction.startChild(
      'process_data',
      description: 'Processing fetched data',
    );
    await Future.delayed(const Duration(milliseconds: 500)); // محاكاة لمعالجة البيانات
    spanProcess.finish(status: const SpanStatus.ok());

  } catch (e) {
    transaction.status = const SpanStatus.internalError();
    await Sentry.captureException(e, stackTrace: StackTrace.current);
  } finally {
    // إنهاء المعاملة
    await transaction.finish();
  }
}

شرح الكود:

  • Sentry.startTransaction(): تبدأ معاملة جديدة لتتبع مجموعة من العمليات.
  • transaction.startChild(): تنشئ نطاقًا فرعيًا داخل المعاملة لتتبع جزء معين من العملية.
  • span.finish(): تنهي النطاق، مع تحديد حالته (نجاح، خطأ، إلخ).
  • transaction.finish(): تنهي المعاملة بأكملها.

2. مراقبة أداء بدء التشغيل والإطارات

يقوم Sentry Flutter تلقائيًا بمراقبة أوقات بدء تشغيل التطبيق والإبلاغ عن الإطارات البطيئة أو المتجمدة، مما يساعدك على تحديد المشاكل التي تؤثر على سلاسة واجهة المستخدم [1]. لا يتطلب هذا إعدادًا إضافيًا بخلاف التهيئة الأساسية.

التكاملات المتقدمة: Dio و User Feedback

يوفر Sentry تكاملات قوية مع مكتبات Flutter الشائعة، بالإضافة إلى ميزات لجمع ملاحظات المستخدمين.

1. تكامل Dio لتتبع طلبات HTTP

إذا كنت تستخدم مكتبة Dio لإجراء طلبات HTTP في تطبيقك، فإن تكامل Sentry مع Dio يوفر تتبعًا تلقائيًا للأخطاء والأداء لطلبات الشبكة [4].

import 'package:dio/dio.dart';
import 'package:sentry_dio/sentry_dio.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

void setupDioClient() {
  final dio = Dio();
  // إضافة SentryInterceptor إلى Dio
  dio.addSentry(
    failedRequestStatusCodes: [
      SentryStatusCode.range(400, 404), // التقاط أخطاء العميل 400-404
      SentryStatusCode(500),           // التقاط أخطاء الخادم 500
    ],
    failedRequestTargets: [
      'api.example.com', // التقاط الأخطاء من هذا النطاق فقط
    ],
  );

  // الآن، أي طلبات تتم عبر هذا الـ dio client سيتم مراقبتها بواسطة Sentry
  // مثال على طلب قد يفشل
  // dio.get('https://wrong-url.dev/');
}

شرح الكود:

  • dio.addSentry(): تقوم بإضافة SentryInterceptor إلى عميل Dio الخاص بك.
  • failedRequestStatusCodes: يمكنك تخصيص رموز حالة HTTP التي تعتبر أخطاء ويجب التقاطها بواسطة Sentry [4].
  • failedRequestTargets: يمكنك تحديد عناوين URL المستهدفة التي ترغب في مراقبة أخطاء الطلبات الفاشلة منها [4].

2. جمع ملاحظات المستخدمين (User Feedback)

تتيح لك ميزة ملاحظات المستخدمين في Sentry جمع معلومات قيمة مباشرة من المستخدمين عند حدوث خطأ، مما يساعدك على فهم المشكلة بشكل أفضل [5].

import 'package:flutter/material.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

// يجب تعريف GlobalKey<NavigatorState> في مكان يمكن الوصول إليه من Sentry.init
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

Future<void> main() async {
  await SentryFlutter.init(
    (options) {
      options.dsn = 'https://examplePublicKey@o0.ingest.sentry.io/0';
      options.navigatorKey = navigatorKey; // مهم لعرض SentryFeedbackWidget
      options.beforeSend = (event, hint) async {
        // يمكنك هنا تحديد متى تريد عرض نموذج ملاحظات المستخدم
        // على سبيل المثال، عند حدوث خطأ معين
        if (event.level == SentryLevel.fatal || event.level == SentryLevel.error) {
          final screenshot = await SentryFlutter.captureScreenshot();
          final context = navigatorKey.currentContext;
          if (context != null && context.mounted) {
            SentryFeedbackWidget.show(
              context,
              associatedEventId: event.eventId,
              screenshot: screenshot,
            );
          }
        }
        return event;
      };
    },
    appRunner: () => runApp(const MyApp()),
  );
}

// ... بقية كود MyApp ...

// يمكنك أيضًا إظهار النموذج يدويًا في أي وقت
void showFeedbackFormManually(BuildContext context, SentryId eventId) {
  SentryFeedbackWidget.show(
    context,
    associatedEventId: eventId,
    // يمكنك إضافة لقطة شاشة هنا إذا كانت متاحة
  );
}

شرح الكود:

  • options.navigatorKey = navigatorKey;: ضروري لتمكين SentryFeedbackWidget من الظهور بشكل صحيح.
  • options.beforeSend: هو callback يتم استدعاؤه قبل إرسال أي حدث إلى Sentry. يمكنك استخدامه لاعتراض الأحداث وعرض نموذج ملاحظات المستخدم بشكل مشروط [5].
  • SentryFlutter.captureScreenshot(): لالتقاط لقطة شاشة للتطبيق يمكن إرفاقها مع ملاحظات المستخدم.
  • SentryFeedbackWidget.show(): تعرض نموذج ملاحظات المستخدم، حيث يمكن للمستخدم إدخال اسمه وبريده الإلكتروني ووصف المشكلة. يتم ربط هذه الملاحظات بالحدث الأصلي في Sentry [5].

نصائح لتحسين SEO وصور المقال

لضمان وصول هذا المقال إلى أكبر عدد من المطورين العرب، إليك بعض النصائح الإضافية:

  • الكلمة المفتاحية: تأكد من تكرار “Sentry Flutter” بشكل طبيعي في جميع أنحاء المقال، خاصة في العناوين والفقرات الأولى والأخيرة.
  • الروابط الداخلية: عند الحديث عن مفاهيم مثل “مراقبة الأداء” أو “تتبع الأخطاء”، يمكنك وضع placeholder مثل [ضع رابط مقال عن مراقبة الأداء في Flutter هنا] لربطها بمقالات أخرى ذات صلة على موقعك.
  • النص البديل للصور (Alt Text): لكل صورة أو لقطة شاشة تضعها في المقال، استخدم نصًا بديلاً وصفيًا يتضمن الكلمة المفتاحية. أمثلة:
    • alt= Sentry Flutter DSN Configuration
    • alt='مثال على التقاط خطأ يدويًا في Flutter باستخدام Sentry'
    • alt='لوحة تحكم Sentry تعرض أداء تطبيق Flutter'
    • alt='نموذج ملاحظات المستخدم في Sentry Flutter'

الخاتمة: هل Sentry Flutter يستحق العناء؟ رأي شخصي

بعد استعراضنا الشامل لميزات Sentry Flutter وكيفية دمجه في تطبيقاتك، يمكنني القول بثقة تامة: نعم، Sentry Flutter يستحق كل العناء وهو أداة لا غنى عنها لأي مطور Flutter جاد.

في عالم تطوير التطبيقات اليوم، حيث يتوقع المستخدمون تجربة خالية من العيوب، لم يعد تتبع الأخطاء يدويًا أو الاعتماد على تقارير المستخدمين كافيًا. يمنحك Sentry القدرة على التحول من رد الفعل إلى الاستباقية، حيث يمكنك اكتشاف المشاكل وإصلاحها قبل أن تؤثر على عدد كبير من المستخدمين. إن الرؤى العميقة التي يوفرها حول الأخطاء والأداء، بالإضافة إلى سهولة التكامل مع Flutter، تجعله استثمارًا حكيمًا في جودة تطبيقك وسمعته.

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

ماذا بعد؟

موقع sentry الرسمي

موقع اضافة Sentry Flutter

اعجبك المقال : شاركه الآن
احمد علي
احمد علي

مطور تطبيقات هواتف ذكية باستخدام Flutter، وصانع محتوى تقني يكتب عن الذكاء الاصطناعي والبرمجة وتطورات التكنولوجيا الحديثة. أسعى لتبسيط الأفكار المعقدة ومشاركة خبرتي مع المهتمين بالمجال.

المقالات: 196

اترك ردّاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *