Flutter
ترسل athar_errors أخطاء Dart والأعطال الأصلية و(إن فعّلتها) آثار التنقّل، مجهّلة، إلى عنوان
الاستقبال الخاص بتطبيقك. ولا تقاطع المستخدم أبدًا.
التثبيت
لم تُنشر بعد
الحزمة غير منشورة على pub.dev بعد: تصلك مع حسابك، بالاسم أدناه.
dependencies:
athar_errors: ^0.1.0
على Android يحتاج التطبيق إذن INTERNET.
التشغيل
void main() => ErrorReporting.runGuarded(() async {
await ErrorReporting.init(const ErrorOptions(
dsn: 'https://ik_…@<your ingest host>/<app id>', // يظهر مرة واحدة مع مفتاح التطبيق
release: '4.2.0+420',
environment: 'production',
appVersion: '4.2.0',
inAppPackages: ['my_app'], // حزمك أنت: إطاراتها تحدّد تجميع المشكلة
));
runApp(const MyApp());
});
runGuardedيبلغ عن الأخطاء التي تفلت إلى الـ zone.initيلتقطFlutterError.onErrorوPlatformDispatcher.instance.onError. وتبقى معالجاتك السابقة تعمل بعده مباشرة، فتتصرّف الأدوات الأخرى ووحدة التصحيح كما كانت.
الأعطال الأصلية
- Android: يُكتب استثناء JVM غير الملتقط في ملف، ثم يعمل المعالج السابق للتطبيق، فينتهي التطبيق
تمامًا كما كان. أما أعطال NDK وحالات ANR فتأتي من سجلات الخروج في النظام (Android 11 وما بعده)،
ولا تحمل مكدّسًا، فيُجمع كل نوع منها في مشكلة واحدة (
NativeCrashوApplicationNotResponding)، مع الإشارة في رسالتها حين يعطيها Android. - iOS: يُكتب
NSExceptionغير الملتقط في ملف. وتأتي الإشارات وعمليات الإنهاء من تقارير أعطال MetricKit (iOS 14 وما بعده)، التي يسلّمها iOS في تشغيل لاحق. - وفي الحالتين يُرسل العطل عند التشغيل التالي بصفته
fatal، مع الإصدار الذي تعطّل.
ما يمكن أن ترسله أيضًا
- خطأ التقطته:
ErrorReporting.captureError(e, stack). - أحداث المنتج:
ErrorReporting.track('checkout.done', {'items': 3}). - مستخدمك:
ErrorReporting.identify('your-user-id'). استعمل معرّفك الخاص غير المفهوم، لا البريد أبدًا. يبقى بين مرات التشغيل، وidentify(null)ينساه. - آثار التنقّل معطّلة افتراضيًا. ومع
breadcrumbs: true:- أضف
ErrorReporting.navigatorObserverإلىnavigatorObservers، فتُسجّل أسماء المسارات قوالبَ (/orders/:id، بلا نص استعلام)؛ - و
ErrorReporting.addBreadcrumb('…')يضيف أثرك الخاص.
- أضف
ملف المستخدم (اختياري)
مع profilesUrl ومفتاح عام profilesKey (pk_…) في ErrorOptions، يضبط
identify('id', email: …, phone: '+…', attributes: {…}) ملف المستخدم أيضًا (وتُجزّأ الخدمة البريد
والهاتف عند وصولهما)، ويسجّل track الحدث هناك أيضًا، ويسجّل
ErrorReporting.setConsent('push', true) اختيار القناة. كل ذلك ينتظر في طابور (200 عنصر على الأكثر،
7 أيام) ويتبع خيار الإيقاف نفسه. ودون هذين الخيارين لا يذهب شيء إلى هناك.
ما تجمعه
- ما يُجمع: نوع الخطأ ورسالته وإطارات المكدّس (الدالة والمكتبة والسطر)، وإصدار التطبيق وبنيته وإطلاقه وبيئته. وكذلك نظام التشغيل وإصداره الرئيسي، وهل الجهاز هاتف أو جهاز لوحي، واللغة. ولا تحمل الإطارات أبدًا المتغيرات المحلية أو المعاملات.
- ما يُمسح على الجهاز أولًا: عناوين البريد وأرقام الهواتف وأي سلسلة من 7 أرقام أو أكثر، وعناوين IP،
والرموز والمفاتيح، ومعرّفات UUID، ونصوص الاستعلام، ومسارات المجلدات الشخصية. يصبح كلٌّ منها
عنصرًا نائبًا (
<email>،<number>…). أضف أنماطك بـscrubPatterns؛ ولا يمكن إيقاف الأنماط المدمجة. - ما لا يُجمع أبدًا: الأسماء، والبريد، وطراز الجهاز أو معرّفاته، ومعرّفات الإعلانات، والموقع،
وعناوين IP، وأي شيء على الشاشة أو مكتوب. ولا واجهة خاصة بها أبدًا. والاستثناء الوحيد اختياري: مع
profilesUrlوprofilesKeyيذهب ما تمرّره إلىidentifyإلى ملف المستخدم.
ما لا تفعله أبدًا
- لا ترمي أي خطأ في تطبيقك. إن تعطّلت الحزمة نفسها أوقفت نفسها حتى نهاية الجلسة.
- دون اتصال: 50 عنصرًا على الأكثر لمدة تصل إلى 7 أيام، ويُسقط الأقدم أولًا، وكل عنصر 64 كيلوبايت على الأكثر. تُرسل حين يعود التطبيق إلى الواجهة، مع تباطؤ متزايد ما دامت الخدمة غير متاحة. والخطأ نفسه إذا تكرّر أكثر من 10 مرات في الدقيقة يُحسب مرة واحدة على الجهاز.
الإيقاف والموافقة
ErrorReporting.setEnabled(false)يوقف الالتقاط ويحذف ما في الطابور، ويبقى كذلك بين مرات التشغيل.- الوضع الصارم (
requireConsent: true) لا يلتقط شيئًا حتىErrorReporting.grantConsent()؛ وrevokeConsent()يحذف ما في الطابور.
سياسة الخصوصية لديك: نموذج
يرسل هذا التطبيق تقارير أخطاء مجهّلة لتساعدنا على إصلاح الأعطال. يحتوي التقرير على الخطأ، وإصدار التطبيق ونظام التشغيل، ونوع الجهاز. ولا يحتوي على اسمك أو بريدك أو حسابك أو موقعك أو عنوان IP أو أي شيء كتبته. يمكنك إيقاف ذلك من الإعدادات ← [مفتاحك]. وتُحفظ التقارير 30 يومًا.
إن ضبطت profilesUrl وprofilesKey فلم يعد هذا النموذج يكفيك: اذكر ما تمرّره إلى identify
(بريد، هاتف، سمات)، وفيمَ يُستعمل ملف المستخدم.