---
url: 'https://www.corbado.com/ar/blog/webauthn-errors'
title: 'الدليل الشامل لأخطاء WebAuthn في الإنتاج (2026)'
description: 'تعرف على معنى أخطاء WebAuthn الشائعة مثل NotAllowedError في الإنتاج وكيفية تصنيفها حسب نوع العملية، والتوقيت، وسياق النظام الأساسي.'
lang: 'ar'
author: 'Vincent Delitz'
date: '2026-07-03T07:10:42.972Z'
lastModified: '2026-07-03T07:10:42.972Z'
keywords: 'أخطاء webauthn, NotAllowedError, AbortError, SecurityError, استكشاف أخطاء WebAuthn, تصنيف أخطاء مفاتيح المرور, أخطاء الإنشاء المشروط, ASAuthorizationError, رموز ASAuthorizationError, androidx.credentials, أخطاء مفتاح مرور Credential Manager, iOS'
category: 'WebAuthn Know-How'
---

# الدليل الشامل لأخطاء WebAuthn في الإنتاج (2026)

## 1. مقدمة

تعد أخطاء WebAuthn في الإنتاج محيرة لأن المتصفحات تعرض مجموعة صغيرة من أسماء `DOMException` (مثل `NotAllowedError`) التي يمكن أن تمثل أسباباً أساسية متعددة. علاوة على ذلك، فإن الغالبية العظمى من "الأخطاء" - غالباً ما تتجاوز 95% في عمليات النشر واسعة النطاق المحسنة - هي في الواقع **سلوك متوقع** (قام المستخدم بإلغاء مطالبة مفتاح المرور لنظام التشغيل).

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

إذا كنت تريد التعريفات الأساسية لهذه الأسماء، فابدأ بـ [MDN `DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException). بالنسبة لشروط WebAuthn المحددة التي تؤدي إلى هذه الاستثناءات (وما الذي يتطلب من المتصفحات فرضه)، راجع [مواصفات مصادقة الويب من W3C](https://www.w3.org/TR/webauthn-3/).

إذا كنت تتعامل مع جميع الأخطاء على أنها "أخطاء برمجية"، فستفعل الأشياء الخاطئة:

- ستلوث مقاييس الأخطاء الخاصة بك بالإلغاءات العادية.
- ستفوتك التراجعات الحقيقية المخفية داخل كتلة `NotAllowedError`.
- ستنشر واجهة مستخدم تربك المستخدمين بدلاً من مساعدتهم على التعافي.

في هذا المقال نجيب على:

- ماذا تعني الأسماء الأكثر شيوعاً لأخطاء WebAuthn في حركة المرور الحقيقية؟
- كيف تميز `NotAllowedError` في مجموعات قابلة للتنفيذ (إلغاء مقابل مهلة مقابل التوفر)؟
- لماذا يعني نفس الخطأ أشياء مختلفة اعتماداً على العملية (تسجيل الدخول بواجهة مستخدم مشروطة مقابل تسجيل الدخول النمطي مقابل إنشاء مفتاح المرور مقابل الإنشاء المشروط)؟
- ما هو الحد الأدنى من السياق الذي يجب أن تلتقطه حتى يصبح "فشل" مشكلة قابلة للتحقيق؟

## Key Facts

- `NotAllowedError` هو **إشارة سطحية**، وليس سبباً جذرياً. يمكن أن يعني الإلغاء، أو المهلة، أو "لا توجد بيانات اعتماد محلية"، أو عدم وجود تنشيط للمستخدم اعتماداً على السياق.
- **نوع العملية يغير المعنى.** نفس `NotAllowedError` يعني أشياء مختلفة أثناء تسجيل الدخول بواجهة مستخدم مشروطة، وتسجيل الدخول النمطي، والإنشاء اليدوي لمفتاح المرور، والإنشاء المشروط، والإضافات التي يتم تشغيلها تلقائياً.
- **التوقيت من بداية العملية** هو الإشارة الأكثر تقليلاً من شأنها: الفشل الفوري (`<1s`)، وإلغاء المستخدم (1-15 ثانية)، والمهلة (30 ثانية فما فوق) هي فئات مختلفة جذرياً.
- `AbortError` هو عادةً مشكلة دورة حياة / تزامن (التنقل، وإعادة العرض، والطلبات المتعددة قيد التشغيل).
- `SecurityError` هو دائماً تقريباً سياسة / سياق ونادر في عمليات النشر الإنتاجية الناضجة.
- "أسماء أخطاء المتصفح" و "رفض تحقق الخادم" هما طبقتان مختلفتان. تتبع رفض الخادم كرموز صريحة، وليس كأخطاء عامة للعميل.
- **أسماء الأخطاء الخام غير قابلة للتنفيذ وحدها.** قم دائماً بالتقاط نوع العملية والتوقيت وسياق النظام الأساسي جنباً إلى جنب مع `error.name` حتى تتمكن من تصنيف الأخطاء في مجموعات يمكنك إصلاحها فعلياً.
- **"البيئة" هي أكثر من مجرد متصفح + نظام تشغيل.** لفهم الأخطاء حقاً، تحتاج إلى تتبع المجموعة الكاملة: إصدار نظام التشغيل، والعميل (إصدار المتصفح / التطبيق)، وإعدادات المصادق (مثل حالة iCloud / GPM) ونموذج الأجهزة المحدد.
- **إخفاقات تسجيل الدخول هي P1، وإخفاقات الإنشاء هي P2.** في حين أن أخطاء الإنشاء (P2) غالباً ما يكون حجمها أكبر بسبب تخلي المستخدم، فإن أخطاء تسجيل الدخول (P1) تمنع الوصول وتتطلب تنبيهاً فورياً.

## 2. ورقة مرجعية للإنتاج

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

| **`error.name`** | **ما يعنيه عادة في الإنتاج** | **ما يجب التحقق منه للتأكيد** | **الإجراء الأول (تجربة المستخدم + الهندسة)** |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `NotAllowedError` | رفض المستخدم الورقة، أو انتهت المهلة، أو عدم تطابق التوفر المدمج في مجموعة واحدة. هذه هي أكبر مجموعة أخطاء في الإنتاج. | وقت الخطأ، وما إذا كانت واجهة الاستجابة السريعة / الهجينة قد ظهرت، وما إذا كان الحفل قد بدأ من إجراء مستخدم حقيقي | تعامل معه على أنه متوقع: استعادة واجهة المستخدم + إظهار خطة احتياطية |
| `AbortError` | أجهض تطبيقك (أو المتصفح) الحفل | التنقل / إعادة العرض أثناء الحفل؛ مكالمات WebAuthn المتزامنة؛ `AbortController.abort()` | فرض طلب واحد قيد التشغيل؛ منع تغييرات المسار؛ التعامل مع الإجهاض كتدفق تحكم عادي |
| `SecurityError` | السياق / السياسة غير مسموح بها | أصل + استراتيجية معرف RP؛ إطار / تضمين؛ HTTPS؛ سياسة الميزة | إصلاح معرف RP / تكوين الأصل؛ التحقق من سياسات التضمين؛ ضمان سياق آمن |
| `InvalidStateError` | عدم تطابق الحالة (غالباً ما يكون تسجيل مكرر) | التسجيل مقابل تسجيل الدخول؛ `excludeCredentials`؛ بيانات اعتماد موجودة على المصادق | تعامل على أنه "مسجل بالفعل"؛ ضبط مسار تجربة المستخدم؛ إصلاح إنشاء الخيارات |
| `ConstraintError` | لا يمكن تلبية المتطلبات | `authenticatorAttachment`، `userVerification`، متطلبات المفتاح المقيم | تخفيف القيود أو توفير مسار / بديل بديل. مثال: قفل الشاشة مفقود على Android |
| `DataError` | المدخلات مشوهة / غير متسقة | ترميز base64url؛ تنسيقات المعرف / التحدي / مقبض المستخدم | إصلاح الترميز / التسلسل؛ إضافة التحقق من الصحة في إنشاء الخيارات |
| `NotSupportedError` | النظام الأساسي / المتصفح لا يدعم ما طلبته | إصدار نظام التشغيل / المتصفح؛ افتراضات اكتشاف الميزات | التراجع فوراً؛ تسجيل القطاع؛ تجنب إظهار عبارات تحث المستخدم على اتخاذ إجراء بشأن مفتاح المرور للبيئات غير المدعومة |
| `UnknownError` | فشل النظام الأساسي / المصادق بطريقة عامة | طفرات بعد تحديثات نظام التشغيل؛ بناء الجهاز؛ مشاكل مزود مدير بيانات الاعتماد | تجربة مستخدم صديقة لإعادة المحاولة؛ التقاط أرقام البناء؛ التحقيق في طفرات القطاع |

هناك شيء واحد يسهل تفويته: يمكن أن يعني نفس `error.name` أشياء مختلفة تماماً اعتماداً على **نوع العملية**. ضع في اعتبارك سياق العملية عند قراءة الأقسام أدناه. في الممارسة العملية، تتفوق أخطاء إنشاء مفتاح المرور (التسجيل) عادةً على أخطاء تسجيل الدخول بهامش كبير - ينطبق الجدول أعلاه على كليهما، لكن الإنشاء هو المكان الذي يعيش فيه معظم الحجم.

بعد ذلك، سنتعمق أكثر في `NotAllowedError` لأنها الأكثر ظهوراً والتي تسيء الفرق تفسيرها في أغلب الأحيان.

## 3. NotAllowedError: إما أن العملية انتهت مهلتها أو لم يُسمح بها

غالباً ما تبدو `NotAllowedError` كـ "فشل مفاتيح المرور"، ولكنها عادةً ما تكون النظام الأساسي الذي يخبرك بأن المستخدم لم يكمل واجهة مستخدم نظام التشغيل. المفتاح هو تقسيمها إلى مجموعات يمكنك التصرف بناءً عليها.

**ما ستراه في وحدة تحكم المتصفح:**

| **المصدر** | **رسالة الخطأ** |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Chrome, Edge | `NotAllowedError: The operation either timed out or was not allowed. See: https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.` |
| Safari, WebKit | `NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.` |
| Safari, WebKit | `NotAllowedError: This request has been cancelled by the user.` |
| Chrome, Edge | `NotAllowedError: The operation is not allowed at this time because the page does not have focus.` |
| Safari, WebKit | `NotAllowedError: The document is not focused.` |
| Firefox | `NotAllowedError: Operation failed.` |

تظهر جميعها كـ `error.name === "NotAllowedError"`. تختلف `error.message` باختلاف محرك المتصفح والسبب الأساسي، لكن النتيجة واحدة: لم يكتمل الحفل.

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

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

### 3.1 التمييز بالسياق

لست بحاجة إلى إشارة مثالية. تحتاج إلى سياق كافٍ لتجنب التعامل مع كل `NotAllowedError` بنفس الطريقة. يحصل iOS / Safari على اهتمام خاص أدناه لأن لديه قيوداً فريدة (متطلبات تنشيط المستخدم في الإصدارات السابقة)، ولكن في حجم الأخطاء الخام، غالباً ما تولد متصفحات Windows و Chromium `NotAllowedError` أكثر من أي نظام أساسي آخر. غالباً ما تصل بك هذه الإشارات إلى 80٪ من الطريق:

| **الإشارة** | **المعنى المحتمل** | **ماذا تفعل بعد ذلك** |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| فشل فوري (`<1s`) | رفض البيئة: لا قدرة، المستند غير مركز، سطح الإنشاء المشروط غير متوفر | التحقق من اكتشاف الميزات؛ تأكد من أن المستند يحتوي على تركيز؛ تحقق من أن العملية مدعومة على هذا النظام الأساسي |
| إلغاء سريع (1-3 ثوانٍ) | مطالبة مفاجئة / بدون سياق | تغيير توقيت المطالبة؛ إضافة تهدئة بعد الإلغاء |
| إلغاء بطول المستخدم (3-15 ثانية) | رأى المستخدم مربع الحوار واختار عدم المتابعة | تجربة مستخدم متوقعة؛ استعادة واجهة المستخدم + عرض احتياطي |
| المهلة (30 ثانية فما فوق) | انتهت مهلة الحفل دون تدخل المستخدم | الدلو باسم "لم يكتمل"؛ ضع في اعتبارك ما إذا كانت المطالبة قد تمت ملاحظتها |
| تظهر واجهة مستخدم QR / الهجينة قبل الفشل | لا توجد بيانات اعتماد محلية متاحة على هذا الجهاز. ملاحظة: يتطلب الكشف الموثوق به عن قرارات رمز الاستجابة السريعة قبل حدوثها طبقة ذكاء مفتاح مرور تعرف ما إذا كانت بيانات اعتماد قابلة للاستخدام موجودة على الجهاز الحالي. | بوابة عروض مفتاح المرور؛ اجعل "استخدام الهاتف" صريحاً؛ تقليل مفاجأة QR |
| تتركز على iOS / Safari وتعمل بدون نقرة / النقر | تنشيط المستخدم مفقود | ابدأ الحفل بإيماءة مستخدم حقيقية |
| أثناء الإنشاء المشروط أو الإضافة المشغلة تلقائياً | التدوين الآلي غير متوفر، أو بيانات الاعتماد موجودة بالفعل، أو فقدت الصفحة التركيز. يمكن أن تظهر أخطاء الإنشاء المشروط بشكل مفاجئ وبأحجام كبيرة عند إطلاق الميزة، مما يجعل هذا أحد أكبر مصادر الأخطاء بين عشية وضحاها. | راجع الإنشاء المشروط؛ تحقق من حالة رؤية المستند؛ استخدم `getClientCapabilities()` للتحقق من دعم `conditionalCreate` قبل محاولة المكالمة |

هذا هو السبب أيضاً في أنه نادراً ما يكون `NotAllowedError` مرئياً للمستخدم. إنها ليست رسالة يمكن للمستخدم التصرف بناءً عليها.

تصنيف السياق هو أيضاً المكان الذي تنقسم فيه معدلات النجاح بشكل حاد. يقيس [تحليل معدل نجاح مصادقة مفتاح المرور لعام 2026](https://www.corbado.com/passkey-benchmark-2026/passkey-authentication-success-rate) إكمال الربع الأول من عام 2026 بنسبة 55-95٪ للتدفقات التي تبدأ بمعرف الجهاز غير المعروف مقابل 95-99٪ لعوائد الجهاز المعروفة عبر عمليات النشر من الشركات إلى المستهلكين واسعة النطاق. يهبط المعرف الأول للويب على iOS بنسبة إكمال 85-95٪ (% CDA 0-5٪)، الويب على Android بنسبة 70-85٪ (% CDA 5-10٪) و macOS للويب بنسبة 70-85٪ (% CDA 10-15٪)، بينما يقع الويب على Windows بنسبة 45-60٪ من الإكمال الأول للمعرف مع % CDA بنسبة 55-65٪ على Windows 11 و 40-55٪ على Windows 10. إن قراءة حجم `NotAllowedError` دون فصل سياقات الجهاز المعروفة مقابل غير المعروفة يجمع بين نظامي نجاح مختلفين تماماً.

فارق بسيط واحد يهم في الإنتاج: قد تعرض بعض وكلاء المستخدمين المهلات كـ `TimeoutError`، لكن العديد من الفرق لا تزال ترى مهلة تنهار إلى `NotAllowedError` في لوحات المعلومات. في كلتا الحالتين، تعامل مع المهلات كـ "لم يكتمل الحفل" وقم بتجميعها باستخدام التوقيت بالإضافة إلى السياق.

### 3.2 معالجة تجربة المستخدم: اجعل الإلغاء خروجاً عادياً

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

- استعادة واجهة مستخدم تسجيل الدخول (لا توجد أداة دوارة تستمر في التشغيل)
- احتفظ بحالة المعرف (لا تفرض إعادة الإدخال)
- إظهار خطة احتياطية مرئية على نفس الشاشة
- تجنب اللافتات المخيفة للنتائج المتوقعة

ما وراء الأساسيات:

- تعامل مع الإلغاء الأول على أنه عادي وعرض إعادة المحاولة مع تفسير هادئ. فقط بعد الإلغاء الثاني يجب أن تقترح خيارات احتياطية (انظر خيارات مفتاح المرور الاحتياطية والاسترداد).
- السماح بما يصل إلى ثلاث مطالبات إنشاء قبل التهدئة حتى يحصل المستخدمون المندهشون على فرصة ثانية (انظر أفضل ممارسات إنشاء مفتاح المرور).
- تقسيم عدد الأخطاء بين الإنشاء وتسجيلات الدخول حتى تقارن المثل بالمثل.
- قسم معدلات الخطأ حسب نظام التشغيل والمتصفح والجهاز حتى تتمكن من تحديد أين يعيش الاحتكاك بالفعل (انظر أفضل ممارسات تسجيل الدخول بمفتاح المرور).

إذا كانت "إلغاءاتك" عالية حقاً، فإن الخطوة التالية هي إصلاح الأسباب الجذرية وراءها: توقيت المطالبة، ومفاجآت QR وانخفاض التوفر.

### 3.3 الإصلاحات الهندسية التي تقلل من NotAllowedError

ابدأ بالتغييرات التي تحرك المقاييس بسرعة:

- إصلاح توقيت المطالبة وتنشيط المستخدم (خاصة على iOS/Safari): أحداث WebAuthn التي يتم تنشيطها بواسطة المستخدم في Safari.
- تقليل مفاجآت QR / الهجينة: لماذا تظهر تدفقات مفتاح المرور رموز QR ويتخلى المستخدمون.
- تقديم العروض البوابة بحيث يتم عرض مفاتيح المرور عندما يكون من المرجح أن تنجح: اعرض مفاتيح المرور فقط عندما يكون من المرجح أن تنجح.
- استخدم الأنماط التي تتجنب المطالبة في حالة عدم وجود بيانات اعتماد محلية: التوسط الفوري لـ WebAuthn.
- **التعامل مع تقلبات الشبكة:** غالباً ما تظهر أخطاء الشبكة أثناء التحقق كأخطاء عامة من جانب العميل. قم بتنفيذ قائمة انتظار غير متصلة بالإنترنت لسجلات القياس عن بُعد الخاصة بك حتى لا تفقد بيانات الخطأ عند انقطاع اتصال المستخدم أثناء الحفل.
- **تأمين الاحتفالات مع واجهات برمجة تطبيقات الكشف** بحيث لا تضخم حالات فشل البيئة مجموعة `NotAllowedError` الخاصة بك. ابدأ بـ `isUVPAA()` باعتبارها البوابة الأساسية، ثم استخدم `getClientCapabilities()` لإجراء عمليات فحص أدق (الإنشاء المشروط، والحصول المشروط، والنقل الهجين، والمصادق على النظام الأساسي). كن على علم بأن واجهات برمجة تطبيقات الكشف يمكن أن تتعطل مع تحديثات نظام التشغيل: شحنت iOS 26.2 خطأ WebKit حيث تعود `isUVPAA()` كـ `false` على جميع المتصفحات القائمة على WKWebView على الرغم من أن مفاتيح المرور تعمل بشكل جيد، مما تسبب في طفرات `NotAllowedError` مفاجئة لـ 10-25% من مستخدمي iOS (انظر إصلاح اكتشاف مفتاح المرور باستخدام `getClientCapabilities()`).

### 3.4 ملاحظة حول أسماء الأخطاء المتطورة

أسماء الأخطاء هدف متحرك. هناك مقترحات مستمرة لإضافة المزيد من أخطاء WebAuthn الدقيقة (على سبيل المثال، لفصل "لا توجد بيانات اعتماد متاحة" عن "ألغى المستخدم"). اعتباراً من فبراير 2026، لم يتم تنفيذ هذا في أي متصفحات، لذا لا يزال من الجدير بناء دلاء السبب الخاصة بك بناءً على السياق والتوقيت. إذا كنت ترغب في تتبع هذا العمل، فراجع [مشكلة WebAuthn #2062](https://github.com/w3c/webauthn/issues/2062) والموضح ["رموز خطأ جديدة"](https://github.com/w3c/webauthn/wiki/Explainer%3A-New-Error-Codes-%282024-Edition%29).

أسماء الأخطاء المتبقية أقل تواتراً ولكنها لا تزال تستحق الفهم عند ظهورها.

## 4. AbortError: تم إجهاض العملية

`AbortError` غير شائع في الحجم مقارنة بـ `NotAllowedError`، ولكن عندما يظهر يكون تشخيصياً للغاية: فهو يعني عادةً أن الحفل لم ينتهِ لأن تطبيقك أبطل الطلب - حدث التنقل، أو تغيرت الحالة، أو بدأ طلب ثانٍ.

**ما ستراه في وحدة تحكم المتصفح:**

| **المصدر** | **رسالة الخطأ** |
| -------------- | --------------------------------------------------------- |
| Chrome, Edge | `AbortError: The operation was aborted.` |
| Chrome, Edge | `AbortError: Aborted by AbortSignal.` |
| Firefox | `AbortError: signal is aborted without reason` |
| Firefox | `AbortError: Operation timed out.` |
| Safari, WebKit | `AbortError: The user aborted a request.` |
| Chrome | `AbortError: CredentialContainer request is not allowed.` |

تشمل أسباب الإنتاج الشائعة ما يلي:

- مكالمات WebAuthn متزامنة متعددة (مطالبتان تتسابقان)
- تغيير المسار / إعادة العرض أثناء حفل قيد التشغيل
- استدعاء `AbortController.abort()` أثناء إعادة المحاولة أو تنظيف الحالة

لإصلاح ذلك، ركز على جعل الحفل "قسماً حرجاً":

- السماح بطلب واحد قيد التشغيل في كل مرة
- منع التنقل أثناء الحفل (أو الإلغاء بشكل نظيف واستعادة واجهة المستخدم)
- التعامل مع الإجهاض كتدفق تحكم متوقع: إظهار زر إعادة المحاولة وطريقة احتياطية

إذا رأيت `AbortError` تتركز في الأسطح المضمنة أو تطبيقات متعددة المجالات، فإن المجموعة التالية التي يجب التحقق منها هي `SecurityError`.

## 5. SecurityError: WebAuthn غير مدعوم على المواقع التي بها أخطاء في شهادة TLS

يخبرك `SecurityError` المتصفح بأن: "هذا السياق لا يُسمح له بالقيام بما طلبته." في الممارسة العملية، يكون دائماً تكويناً تقريباً، وليس سلوك المستخدم. في عمليات النشر الإنتاجية الناضجة، نادرًا ما يكون `SecurityError` لأن هذه المشكلات عادةً ما يتم التقاطها أثناء اختبار التكامل. إذا ظهر في الإنتاج، فعادةً ما يعني ذلك أنه تم إضافة مجال جديد أو سياق تضمين أو هدف نشر بدون تكوين WebAuthn مناسب.

تشمل الأسباب الشائعة ما يلي:

- عدم تطابق معرف RP / الأصل (الإعدادات متعددة المجالات)
- قيود التضمين عبر الأصول (iframes)
- سياق غير آمن (ليس HTTPS) أو الأذونات / السياسات المحظورة
- `.well-known/webauthn` أو `.well-known/assetlinks.json` تم تكوينه بشكل غير صحيح أو مفقود أو غير متوفر مؤقتاً. ستتسبب مشكلات الشبكة خلال النافذة الحرجة عندما يجلب المتصفح هذه الملفات في حدوث أعطال. النقطة العمياء الشائعة: إذا كانت صفحتك الرئيسية معطلة للصيانة، فإن الملفات المعروفة تكون غير متصلة بالإنترنت، مما يكسر احتفالات مفتاح المرور عبر جميع الأطراف المعتمدة التي تعتمد عليها.

**ما ستراه في وحدة تحكم المتصفح:**

| **المصدر** | **رسالة الخطأ** |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Chrome, Edge | `SecurityError: WebAuthn is not supported on sites with TLS certificate errors.` |
| Any browser | `SecurityError: The relying party ID is not a registrable domain suffix of, nor equal to the current origin's effective domain.` |
| Chrome (iframe) | `SecurityError: The 'publickey-credentials-create' feature is not enabled in this document.` |

في الإنتاج، يعتبر `SecurityError` نادراً - يتم التقاط هذه الأشياء دائماً تقريباً أثناء اختبار التكامل. عند ظهورها، يكون خطأ شهادة TLS هو الناجي الأكثر شيوعاً.

حلقة التصحيح الأسرع هي:

- تسجيل مدخلات الأصل ومعرف RP التي استخدمتها
- إعادة الإنتاج في نفس السياق (المستوى الأعلى مقابل iframe، مجال الإنتاج مقابل التقسيم المرحلي)
- إذا قمت بتضمين تسجيل الدخول، فقم بتأكيد تكوين سياسة الأذونات (على سبيل المثال `publickey-credentials-create` / `publickey-credentials-get`): [MDN Permissions-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Permissions-Policy/publickey-credentials-create)
- التحقق من استراتيجية المجال الخاصة بك (راجع الأصول ذات الصلة)
- إذا كنت تستخدم iframes، فتحقق من صحة سياسات الميزات (راجع مفاتيح مرور iframe)

بمجرد التعامل مع `SecurityError`، فإن المجموعة التالية التي يجب التعامل معها بجدية هي مجموعة الأخطاء التي تشير غالباً إلى أخطاء في التنفيذ: `InvalidStateError` و `ConstraintError` و `DataError`.

## 6. InvalidStateError و ConstraintError و DataError: تعامل معها كأخطاء تنفيذ

يجب أن تكون هذه الأخطاء نادرة في التنفيذ الناضج لمفتاح المرور. عندما تظهر، فإنها تشير عادةً إلى أن إنشاء الخيار خاطئ لقطاع ما أو أن التدفق في الحالة الخاطئة.

### 6.1 InvalidStateError: "تم تسجيل بيانات الاعتماد بالفعل مع الطرف المعتمد"

**ما ستراه في وحدة تحكم المتصفح:**

| **المصدر** | **رسالة الخطأ** |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Safari, WebKit | `InvalidStateError: The user attempted to register an authenticator that contains one of the credentials already registered with the relying party.` |
| Chrome, Edge | `InvalidStateError: At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator.` |
| Chrome, Edge | `InvalidStateError: A request is already pending.` |
| Firefox | `InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable` |

المعاني النموذجية:

- التسجيل: حاولت إنشاء بيانات اعتماد موجودة بالفعل (نسخة مكررة)
- تسجيل الدخول: أقل شيوعاً؛ غالباً ما يعني أن التدفق / الحالة غير متسقة للمنصة

التعامل العملي:

- إذا حدث ذلك في التسجيل اليدوي، تعامل معه على أنه "تم التسجيل بالفعل" وقم بتوجيهه وفقاً لذلك
- تأكد من أن `excludeCredentials` يسرد جميع معرفات بيانات الاعتماد الموجودة للمستخدم حتى يتمكن المصادق من اكتشاف التكرارات (راجع excludeCredentials)
- أثناء الإنشاء المشروط، من المتوقع حدوث `InvalidStateError` ويجب تجاهله بصمت: هذا يعني أن مفتاح المرور موجود بالفعل في المزود. ينطبق الشيء نفسه على `NotAllowedError` و `AbortError` أثناء الإنشاء المشروط (راجع [الإنشاء المشروط على Chrome](https://developer.chrome.com/docs/identity/webauthn-conditional-create))

### 6.2 ConstraintError

المعنى النموذجي: لا يستطيع المصادق تلبية القيود المطلوبة.

المشغلات الشائعة:

- قفل شاشة الجهاز مفقود (خاصة على Android): يتطلب النظام الأساسي التحقق من المقاييس الحيوية أو رقم التعريف الشخصي ولكن الجهاز لا يحتوي على شاشة قفل تم تكوينها
- افتراضات `authenticatorAttachment` أو المفتاح المقيم صارمة جداً
- متطلبات `userVerification` الصارمة في القطاعات حيث لا تتوفر

الإصلاح: قم بتخفيف القيود (حيث يكون ذلك مقبولاً) أو توفير مسار بديل. بالنسبة لقفل الشاشة المفقود، فكر في اكتشاف هذا الشرط وتوجيه المستخدمين بدلاً من الفشل بصمت (Android).

### 6.3 DataError

المعنى النموذجي: المدخلات مشوهة أو غير متسقة.

المشغلات الشائعة:

- أخطاء التشفير (base64 مقابل base64url)
- تنسيق معرفات بيانات الاعتماد غير الصالحة / التحدي

الإصلاح: التحقق من صحة المدخلات وتطبيعها في الحدود التي تولد فيها خيارات WebAuthn. في الممارسة العملية، يكون `DataError` غائباً بشكل فعال في أنظمة الإنتاج الناضجة - إذا تم اختبار إنشاء الخيارات الخاص بك، فلن ترى هذا في لوحات المعلومات.

إذا كانت هذه الأخطاء تحت السيطرة، فإن السؤال التالي هو التغطية: هل يفشل المستخدمون لأن البيئة لا تستطيع القيام بـ WebAuthn بالطريقة التي تتوقعها؟

## 7. NotSupportedError: وكيل المستخدم لا يدعم بيانات اعتماد المفتاح العام

يُعد `NotSupportedError` إشارة تغطية، وليس إشارة موثوقية. ويعني هذا عادةً أن القطاع لا يستطيع القيام بما طلبته (نظام التشغيل / المتصفح قديم جداً، والقدرة مفقودة، والميزة غير ممكّنة).

**ما ستراه في وحدة تحكم المتصفح:**

| **المصدر** | **رسالة الخطأ** |
| --------------------- | ---------------------------------------------------------------------------------------------- |
| Chrome, Edge | `NotSupportedError: The user agent does not support public key credentials.` |
| Firefox | `NotSupportedError: Resident credentials or empty 'allowCredentials' lists are not supported.` |
| Chrome, Edge, Firefox | `TypeError: PublicKeyCredential.parseCreationOptionsFromJSON is not a function` |
| Chrome, Edge, Firefox | `TypeError: PublicKeyCredential.parseRequestOptionsFromJSON is not a function` |
| Chrome, Edge, Firefox | `TypeError: credential.toJSON is not a function` |
| Safari | `TypeError: Can only call PublicKeyCredential.toJSON on instances of PublicKeyCredential` |

الخطآن الأولان هما بالفعل DOMExceptions من نوع `NotSupportedError`. في حين أن إدخالات `TypeError` هي تقنياً نوع استثناء مختلف ولكنها تمثل نفس فئة المشكلة: المتصفح أو البيئة لا تدعم ما طلبته. تُعد عائلة تسلسل JSON `TypeError` أكثر شيوعاً في الممارسة العملية من DOMException الخاص بـ `NotSupportedError` (انظر أدناه).

تشمل الأسباب الشائعة ما يلي:

- المتصفحات / إصدارات نظام التشغيل القديمة التي لا تدعم WebAuthn الأساسي
- طلب ميزات WebAuthn غير متوفرة على هذا النظام الأساسي
- محاولة التدفقات الخاصة بالمنصة على الأجهزة غير المدعومة

**عائلة تسلسل JSON هي أكبر مصدر لفشل فئة `NotSupportedError` في الإنتاج.** من الناحية الفنية، تظهر هذه الأخطاء كـ `TypeError` (طريقة مفقودة)، وليس كـ `DOMException`، ولكن هذا هو المكان الذي ستواجهها فيه. هناك سببان جذريان متميزان:

1. **لا يدعم المتصفح طرق تسلسل WebAuthn JSON.** يحتوي المتصفح على `navigator.credentials` ولكن ليس `PublicKeyCredential.parseCreationOptionsFromJSON` / `parseRequestOptionsFromJSON`. يمثل هذا ما يقرب من 90٪ من عائلة الخطأ هذه، ويتركز في إصدارات Safari و Chrome الأقدم. إذا كانت مكتبة العميل الخاصة بك تعتمد على هذه الطرق بدون احتياطي، فإن ذلك يؤدي إلى حجم خطأ كبير.
2. **ملحقات مدير كلمات المرور تعطل `.toJSON()`.** يمكن للإضافات مثل Bitwarden أو LastPass أو 1Password اعتراض الحفل وإرجاع كائن يشبه بيانات الاعتماد ولكنه ليس نسخة فعلية من `PublicKeyCredential`. يؤدي استدعاء `.toJSON()` عليه إما إلى حدوث خطأ، أو إرجاع قيمة غير محددة، أو أن يكون الكائن فارغاً تماماً. هذا يمثل حوالي 10٪ من العائلة ولكنه محير بشكل خاص في تصحيح الأخطاء لأن رسائل الخطأ تختلف باختلاف المتصفح (Safari: "لا يمكن الاستدعاء إلا على مثيلات PublicKeyCredential"؛ Firefox: "لا ينفذ واجهة PublicKeyCredential").

يجب أن يكون التعامل صريحاً وسريعاً:

- التراجع فوراً إلى كلمة المرور الاحتياطية / كلمة المرور لمرة واحدة
- تسجيل المقطع حتى تتمكن من تحديد ثغرات التغطية كمياً
- تجنب إظهار عبارات الحث على اتخاذ إجراء بشأن مفتاح المرور على القطاعات التي ستفشل باستمرار

إذا كانت التغطية تبدو جيدة ولكن الفشل لا يزال يحدث في قطاعات معينة، فقد تكون تتعامل مع مشكلات طبقة النظام الأساسي التي تظهر على شكل `UnknownError`.

## 8. UnknownError: حدث خطأ غير معروف أثناء التحدث إلى مدير بيانات الاعتماد

يُعد `UnknownError` خطأً جامعاً لفشل المصادق / نظام التشغيل الذي لا يتم تعيينه بشكل نظيف للفئات الأخرى. غالباً ما يكون عابراً، ولكن يمكن أن يرتفع أيضاً بعد تحديثات نظام التشغيل.

**ما ستراه في وحدة تحكم المتصفح:**

| **المصدر** | **رسالة الخطأ** |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| Chrome (Android) | `UnknownError: An unknown error occurred while talking to the credential manager.` |
| Any browser | `UnknownError: The operation failed for an unknown transient reason.` |
| Any browser | `UnknownError: Either the device has received unexpected request data, or the device has been reconfigured since the request was made.` |
| Any browser | `UnknownError: Something went wrong.` |
| Chrome (LastPass) | `TypeError: Cannot use 'in' operator to search for 'type' in null` |
| Safari (LastPass) | `TypeError: null is not an Object. (evaluating 'key in input')` |
| Chrome (Bitwarden) | `FallbackRequested` |

التعامل العملي:

- استخدم واجهة مستخدم صديقة لإعادة المحاولة (لا "تلوم المستخدم")
- التقاط أرقام نظام التشغيل / البناء وسياق مدير الاعتماد / المزود حيثما أمكن ذلك
- مراقبة الطفرات الخاصة بقطاع معين بعد تحديثات نظام التشغيل

مصدر خطأ متخصص واحد لا يتناسب بشكل أنيق مع أي فئة `DOMException`: يمكن لـ **ملحقات متصفح مدير كلمات المرور** (مثل Bitwarden، LastPass، 1Password، وغيرها) اعتراض مكالمات WebAuthn API وإرجاع استجابات غير قياسية. على الرغم من صغر حجمها مقارنة بإلغاءات المستخدم، فإن هذه الأمور تستحق التتبع لأنها تؤثر على شرائح محددة من المستخدمين بشكل مستمر وتكون الأعراض محيرة: طرق مفقودة في كائن بيانات الاعتماد التي تم إرجاعها، أو أنواع أخطاء غير متوقعة، أو استجابات مشوهة لا تتطابق مع أي خطأ WebAuthn موثق. غالباً ما تظهر هذه كـ `UnknownError` أو كاستثناءات غير مصنفة. إذا رأيت طفرات خطأ تتركز في متصفحات معينة مع عدم وجود تفسير على مستوى نظام التشغيل، فتحقق مما إذا كان امتداد مدير الاعتماد متورطاً.

لقد غطينا حتى الآن أسماء أخطاء متصفح الويب. ولكن إذا قمت أيضاً بشحن تطبيقات أصلية، فإن مشهد الأخطاء يكون مختلفاً - ومن نواحٍ عديدة، أفضل بكثير.

## 9. كلمة حول التطبيقات الأصلية (iOS و Android)

يغطي كل ما سبق متصفحات الويب. تشارك التطبيقات الأصلية - iOS مع إطار عمل ASAuthorization و Android مع واجهة برمجة تطبيقات Credential Manager - نفس الفئات الأساسية للأخطاء ولكنها تختلف بطرق مهمة:

1. **"لا توجد بيانات اعتماد" هي إشارة مميزة.** على الويب، تجمع المتصفحات "لا توجد بيانات اعتماد متوفرة" و "ألغى المستخدم" في نفس `NotAllowedError` للخصوصية. على المستوى الأصلي، يؤدي استخدام `preferImmediatelyAvailableCredentials` على نظام iOS (`ASAuthorizationController`) أو `setPreferImmediatelyAvailableCredentials(true)` على نظام Android (`GetCredentialRequest`) إلى إخبار نظام التشغيل بتقديم بيانات الاعتماد الموجودة بالفعل على الجهاز فقط والفشل فوراً في حالة عدم وجود أي منها. يمنحك هذا إرجاعاً نظيفاً لـ "عدم وجود بيانات اعتماد" لا يمكن أن يوفره الويب.

2. **تظهر حالة مزود بيانات الاعتماد.** يمكن للأنظمة الأساسية الأصلية في بعض الظروف أن تخبرك في حالة عدم تثبيت مزود بيانات اعتماد (مثل Google Password Manager، iCloud Keychain، 1Password، إلخ) أو تكوينه أو تعيينه كإعداد افتراضي والتفاعل مع ذلك. على الويب، يتم إخفاء هذه المعلومات خلف رسائل `NotAllowedError` غير الشفافة.

3. **رسائل الخطأ أكثر تحديداً.** نظراً لأن المستخدم قام بتثبيت التطبيق - وبالتالي إنشاء علاقة ثقة مع الطرف المعتمد - يعرض نظام التشغيل تفاصيل تشخيصية أكثر. لا تنطبق اعتبارات الخصوصية التي تجبر متصفحات الويب على أن تكون غامضة بنفس الطريقة عندما يكون التطبيق موجوداً بالفعل على الجهاز. يعرض نظام التشغيل iOS رسائل مترجمة بلغة جهاز المستخدم. يُرجع Android أنواع أخطاء منظمة تحتوي على سلاسل الأسباب. وهذا يجعل تصحيح الأخطاء أسهل ولكن هذا يعني أن معالجة الأخطاء يجب أن تأخذ في الاعتبار الأقلمة وتنسيقات الأخطاء الخاصة بالمنصة.

### 9.1 نظام iOS (إطار عمل ASAuthorization)

يعرض نظام iOS أخطاء مفتاح المرور من خلال إطار عمل ASAuthorization. تصل جميع الأخطاء في رد الاتصال المفوض `authorizationController(controller:didCompleteWithError:)` ككائنات `NSError`.

**التصنيف حسب المجال + الرمز، وليس حسب سلسلة الرسائل.** مجال الخطأ الأساسي هو `com.apple.AuthenticationServices.AuthorizationError` (`ASAuthorizationError.errorDomain`). قم بإلقاء الخطأ باستخدام `let nsError = error as NSError` وقم بمطابقته على `.domain` و `.code`. لا تتطابق أبداً على `.localizedDescription` في الإنتاج - يتم ترجمة رسائل Apple إلى أكثر من 30 لغة ويمكن أن تتغير عبر إصدارات نظام التشغيل. تُعد سلاسل الرسائل المدرجة أدناه مفيدة للتعرف على الأخطاء في السجلات، ولكنها ليست معايير تصنيف.

**رموز ASAuthorizationError العامة:**

| **الرمز** | **الاسم** | **منذ** | **ماذا يعني** |
| -------- | --------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1000 | `Unknown` | iOS 13 | لا ينبغي أن يظهر في الإنتاج. خطأ جامع. |
| 1001 | `Canceled` | iOS 13 | رفض المستخدم ورقة مفتاح المرور. الخطأ الأكثر شيوعاً بشكل عام - المكافئ لـ `NotAllowedError`. إشارة واضحة بـ `userInfo` فارغ ولا يوجد خطأ أساسي. |
| 1002 | `InvalidResponse` | iOS 13 | تلف على مستوى الإطار. نادر في الممارسة العملية. |
| 1003 | `NotHandled` | iOS 13 | لم يعالج أي مزود الطلب. تحقق من الاستحقاقات وتكوين مزود بيانات الاعتماد. |
| 1004 | `Failed` | iOS 13 | فشل عام. يحتوي `localizedDescription` على السبب الفعلي (مثل "التطبيق ذو المعرف X غير مرتبط بالمجال Y"). قد يحتوي `userInfo` على سلسلة `FailureReason`، ولكن لا يتم دائماً ملء `NSUnderlyingErrorKey` - تُرجع إخفاقات اقتران المجال القيمة الخالية للخطأ الأساسي. |
| 1005 | `NotInteractive` | iOS 15 | لا تتوفر بيانات اعتماد عند استخدام `preferImmediatelyAvailableCredentials`. هذه هي إشارة "لم يتم العثور على" النظيفة - يعادل iOS "لا يوجد مفتاح مرور على هذا الجهاز". لم تظهر واجهة مستخدم. |
| 1006 | `MatchedExcludedCredential` | iOS 18 | يوجد مفتاح مرور بالفعل لهذا الطرف المعتمد على هذا الجهاز. إشارة نظيفة لاكتشاف التكرارات - `userInfo` فارغ، لا يوجد `NSUnderlyingErrorKey`. التصنيف يعمل بدون مطابقة السلسلة. |
| 1007 | `CredentialImport` | iOS 18.2 | فشل استيراد بيانات الاعتماد. |
| 1008 | `CredentialExport` | iOS 18.2 | فشل تصدير بيانات الاعتماد. |
| 1009 | `PreferSignInWithApple` | iOS 26 | يفضل المستخدم تسجيل الدخول باستخدام Apple بدلاً من مفتاح المرور. جديد في نظام iOS 26. |
| 1010 | `DeviceNotConfiguredForPasskeyCreation` | iOS 26 | الجهاز يفتقر إلى تكوين رمز المرور أو iCloud Keychain. خلل معروف في محاكي iOS 26: يُرجع 1010 حتى عندما يكون التكوين صحيحاً (لا يُعاد إنتاجه على الأجهزة المادية). |

التمييز الأكثر أهمية للإنتاج: **منذ نظام التشغيل iOS 18، تعرض بيانات الاعتماد المكررة رمز الخطأ الخاص بها 1006 (`MatchedExcludedCredential`).** على نظام التشغيل iOS 17 والإصدارات الأقدم، كانت بيانات الاعتماد المكررة مخفية داخل الرمز 1004 (`Failed`). في نظام التشغيل iOS 18 والإصدارات الأحدث، يكون التمييز هيكلياً (رمز خطأ مختلف)، وليس نصياً.

**أخطاء وقت التشغيل الشائعة (مرجع على مستوى السجل):**

تظهر هذه الرسائل في `localizedDescription` أو في `userInfo` لسيناريوهات فشل محددة. استخدمها لعمليات البحث عن السجلات وتصحيح الأخطاء، وليس للتصنيف البرمجي.

| **الرسالة (باللغة الإنجليزية)** | **الرمز الأساسي** | **ملاحظات** |
| ------------------------------------------------------------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `Application with identifier <TeamID.BundleID> is not associated with domain X` | 1004 (`Failed`) | استحقاق المجالات المرتبطة للتطبيق لا يتطابق مع الطرف المعتمد. أصلح ملف `apple-app-site-association` على الخادم الخاص بك. |
| `Couldn't communicate with a helper application.` | 1004 (`Failed`) | فشل ملحق مزود الاعتماد في الاستجابة. عابر - إعادة المحاولة مناسبة. |
| `Request already in progress for specified application identifier.` | 1004 (`Failed`) | تم إطلاق طلب ASAuthorization مكرر بينما كان أحدهما معلقاً. حالة السباق في التطبيق. |
| `Stolen Device Protection is enabled and biometry is required.` | 1004 (`Failed`) | تمنع حماية الأجهزة المسروقة في نظام التشغيل iOS 17+ المصادقة البيومترية في مواقع غير مألوفة. غير قابل للتنفيذ من قبل المطورين، ولكنه يستحق الظهور للمستخدم. |
| `(AuthenticationServicesCore.ASCABLEClient.ClientError error 2.)` | مجال منفصل | فشلت مصافحة البلوتوث عبر الأجهزة (المهجنة / CABLE). |
| `(AuthenticationServicesCore.ASCABLEClient.ClientError error 3.)` | مجال منفصل | فشل اتصال بلوتوث عبر الأجهزة. |

**رسائل "لا توجد بيانات اعتماد" المترجمة (الرمز 1005):**

عند تعيين `preferImmediatelyAvailableCredentials` ولم يكن هناك مفتاح مرور، يُرجع iOS الرمز 1005 (`NotInteractive`) مع رسالة مترجمة بلغة جهاز المستخدم. هذا فريد للتطبيقات الأصلية - لا تعرض متصفحات الويب هذه الإشارة أبداً. تبدأ الرسالة دائماً بـ `The operation couldn't be completed.` متبوعة بالنص المترجم:

| **اللغة** | **الرسالة** |
| --------------------- | ------------------------------------------------------------------------------------ |
| الصينية المبسطة | `没有可用于登录的凭证。` |
| الفيتنامية | `Không có sẵn thông tin để đăng nhập.` |
| العربية | `لا تتوفر بيانات اعتماد لتسجيل الدخول.` |
| الإسبانية | `No hay ninguna credencial disponible para iniciar sesión.` |
| الصينية (التقليدية) | `沒有可用於登入的憑證。` |
| الكورية | `로그인을 위한 자격 증명이 없습니다.` |
| الفرنسية (كندا) | `Aucun identifiant disponible pour la connexion.` |
| البرتغالية (البرازيل) | `Nenhuma credencial disponível para login.` |
| الفرنسية (فرنسا) | `Aucune information d'identification n'est disponible pour procéder à la connexion.` |
| التايلاندية | `ไม่มีข้อมูลประจำตัวสำหรับเข้าสู่ระบบ` |
| الإيطالية | `Non ci sono credenziali disponibili per l'accesso.` |
| الهولندية | `Geen inloggegevens beschikbaar.` |
| اليابانية | `ログイン用の資格情報がありません。` |
| التركية | `Oturum açmak için kullanılabilecek kimlik bilgisi yok.` |

عادةً ما تعمل أجهزة الإعدادات المحلية باللغة الإنجليزية على حل "عدم وجود بيانات اعتماد" على مستوى واجهة برمجة التطبيقات قبل أن يعرض إطار عمل ASAuthorization خطأ محلياً، ولهذا السبب لا يظهر أي متغير باللغة الإنجليزية أعلاه. برمجياً، قم دائماً بالمطابقة على الرمز 1005 بدلاً من تحليل هذه السلاسل.

### 9.2 Android (واجهة برمجة تطبيقات Credential Manager)

يعرض Android أخطاء مفتاح المرور من خلال واجهة برمجة تطبيقات Credential Manager (`androidx.credentials`). تتضمن رسائل الخطأ رسالة أساسية وغالباً `cause` تحتوي على تفاصيل إضافية. بالمقارنة مع iOS، يوفر Android أنواع أخطاء أكثر تنظيماً وأسباباً أكثر وضوحاً لمشكلات التكوين.

**إلغاء المستخدم واكتشاف بيانات الاعتماد:**

| **الخطأ** | **ملاحظات** |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `User cancelled the operation` | رفض المستخدم مطالبة مفتاح المرور. المكافئ لـ `NotAllowedError`. ملاحظة: يُرجع مدير الاعتماد أيضاً `User canceled the request` (تهجئة الولايات المتحدة) من مسار رمز مختلف - كلاهما متطابقان. |
| `Excluded credential matches existing credential` | يوجد مفتاح مرور بالفعل لمعرف بيانات الاعتماد هذا. المكافئ لـ `InvalidStateError`. على عكس iOS، تختلف الرسالة عن إلغاء المستخدم. |
| `No create options available.` | لا يوجد مزود بيانات اعتماد مؤهل يمكنه معالجة طلب الإنشاء. عادةً ما يعني هذا أن خدمات Google Play قديمة أو لا يوجد مزود بيانات اعتماد يدعم إنشاء مفتاح المرور. |

**أخطاء التكوين والأمان:**

| **الخطأ** | **ملاحظات** |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Passkeys not supported for this app` | روابط الأصول الرقمية (`assetlinks.json`) مفقودة أو لا تحتوي على بصمة شهادة توقيع التطبيق. المكافئ لـ `SecurityError`. |
| `Https failed: respCode=301, url=https://<domain>/.well-known/assetlinks.json` | يُرجع ملف `assetlinks.json` إعادة توجيه بدلاً من HTTP 200. يتطلب Android الملف الموجود في عنوان URL الدقيق دون عمليات إعادة توجيه. |
| `The incoming request cannot be validated` | لا يمكن لمدير الاعتمادات التحقق من الطلب ضد روابط الأصول الرقمية. |
| `RP ID cannot be validated.` | معرّف الطرف المعتمد في خيارات WebAuthn لا يتطابق مع `assetlinks.json`. |
| `Screen lock is missing.` | لم يتم تكوين رمز PIN أو النمط أو المقاييس الحيوية على الجهاز. تتطلب مفاتيح المرور التحقق من المستخدم. يعادل `ConstraintError`. |
| `Cannot find an eligible account.` | لا يوجد حساب Google على الجهاز مؤهل لإنشاء مفتاح المرور (نادر، عادةً ما تكون إعدادات مؤسسة مخصصة). |

**أخطاء المنصة والمصادق:**

| **الخطأ** | **ملاحظات** |
| ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Unsuccessful result from folsom activity.` | فشل داخلي في خدمات Google Play. "Folsom" هو أحد مكونات GMS لعمليات مفتاح المرور. عابر - إعادة المحاولة مناسبة. |
| `Can't find the proper key to decrypt the private key from WebauthnCredentialSpecifics.` | يوجد مفتاح مرور متزامن ولكن لا يمكن للجهاز فك تشفير مفتاحه الخاص. حالة مزامنة Google Password Manager غير متسقة - تمت مزامنة بيانات الاعتماد من جهاز آخر ولكن مفتاح فك التشفير غير متوفر. غير قابل للتنفيذ من قبل المطورين. |
| `Operation was interrupted` (السبب: `The UI was interrupted - please try again.`) | تمت مقاطعة واجهة مستخدم Credential Manager بسبب نشاط آخر (مكالمة واردة، دوران الشاشة، تطبيق في الخلفية). المكافئ لـ `AbortError`. |
| `Unknown credential error` | خطأ عام جامع عندما لا ينطبق أي نوع خطأ محدد. عادةً ما يكون عابراً. |
| `timeout` (السبب: `Canceled`) | انتهت مهلة عملية Credential Manager قبل أن يكمل المستخدم التحقق البيومتري. |

## 10. تجميع كل ذلك: تصنيف الأخطاء

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

```mermaid
flowchart TD
    %% Global Styles
    classDef expected fill:#e3f2fd,stroke:#1565c0,stroke-width:2px;
    classDef unexpected fill:#ffebee,stroke:#c62828,stroke-width:2px;
    classDef network fill:#fff3e0,stroke:#ef6c00,stroke-dasharray: 5 5;
    classDef env fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px;
    classDef action fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;

    %% --- LEFT SIDE: NETWORK & SERVER ---
    subgraph Infrastructure ["البنية التحتية (الخادم / الشبكة)"]
        direction TB
        ServerErr["خطأ في جانب الخادم<br/>500 / خطأ منطقي"]:::network
        NetErr["خطأ في الشبكة<br/>المهلة / 400 طلب غير صالح"]:::network

        ServerErr & NetErr -->|يظهر كـ| ClientManifest["خطأ عام من جانب العميل"]
    end

    %% --- CENTER: THE ENVIRONMENT STACK (From Sketch) ---
    subgraph Environment ["البيئة (جانب العميل)"]
        direction TB

        %% Layer 1: Platform Type
        subgraph Type ["الطبقة 1: المنصة"]
            Web["الويب / المتصفح"]
            Native["أصلي / تطبيق"]
        end

        %% Layer 2: OS Context
        subgraph OS_Layer ["الطبقة 2: نظام التشغيل والإصدار"]
            OS_Web["نظام التشغيل: Windows, macOS, Linux"]
            OS_Nat["نظام التشغيل: iOS, Android"]
            OS_Ver["إصدار نظام التشغيل / الإعدادات<br/>(قفل الشاشة، المقاييس الحيوية)"]

            Web --> OS_Web
            Native --> OS_Nat
            OS_Web & OS_Nat --> OS_Ver
        end

        %% Layer 3: Client Software
        subgraph Client_Layer ["الطبقة 3: برنامج العميل"]
            Browser["المتصفح: Chrome, Safari, Edge<br/>+ الإصدار"]
            App["التطبيق الأصلي / WebView<br/>+ إصدار التطبيق"]

            OS_Ver --> Browser
            OS_Ver --> App
        end

        %% Layer 4: WebAuthn Operation
        subgraph Op_Layer ["الطبقة 4: عملية WebAuthn"]
            OpType{"نوع العملية"}

            Login["تسجيل الدخول<br/>(navigator.credentials.get)"]
            Reg["التسجيل<br/>(navigator.credentials.create)"]

            Browser & App --> OpType
            OpType --> Login
            OpType --> Reg
        end

        %% Layer 5: Sub-types & Complexity
        subgraph Modality ["الطبقة 5: الطريقة والتعقيد"]
            Sub_CUI["CUI / واجهة مستخدم مشروطة"]
            Sub_Auto["عملية تلقائية"]
            Sub_CDA["CDA / المصادقة عبر الأجهزة"]

            Login & Reg --> Sub_CUI
            Login & Reg --> Sub_Auto
            Login & Reg --> Sub_CDA
        end
    end

    %% --- BOTTOM: CLASSIFICATION & ACTION (The "What here?" section) ---
    subgraph Analysis ["تحليل الأخطاء ووقت التشغيل"]
        direction TB

        %% Classification
        Classification{"التصنيف"}

        Exp["خطأ متوقع<br/>(ألغى المستخدم الحفل)"]:::expected
        Unexp["خطأ غير متوقع<br/>(نظام / تعطل / غير معروف)"]:::unexpected

        ClientManifest --> Classification
        Sub_CUI & Sub_Auto & Sub_CDA --> Classification

        Classification --> Exp
        Classification --> Unexp

        %% Detection Logic
        subgraph Detection ["أهداف الكشف"]
            P1["P1: مشاكل تسجيل الدخول"]
            P2["P2: مشاكل الإنشاء"]
            Baseline["كشف انجراف خط الأساس<br/>(زيادة المتوقع)"]
            NewErr["كشف الانحرافات الجديدة<br/>(زيادة غير المتوقع)"]
        end

        Exp --> Baseline
        Unexp --> NewErr
        Exp & Unexp --> P1 & P2

        %% Actionable Outcomes
        subgraph Action ["إجراءات التخفيف"]
            Fix["نشر إصلاح عاجل / إصدار جديد"]:::action
            Fallback["تنشيط الخطة الاحتياطية التلقائية<br/>(تعطيل مفتاح المرور)"]:::action
        end

        P1 & P2 & NewErr --> Fix
        P1 & P2 & NewErr --> Fallback
    end

    %% Connectors
    Infrastructure -.-> Environment
```

الفكرة الأساسية: لا يكون `error.name` الخام منطقياً إلا بمجرد معرفة أي طبقة من البيئة أنتجته، والعملية التي كانت قيد التشغيل، وما إذا كان الخطأ متوقعاً أو غير متوقع. تغطي الأقسام أدناه ما يجب تسجيله وكيفية التصرف بناءً عليه.

## 11. ما يجب تسجيله حتى تصبح الأخطاء قابلة للتصحيح

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

الشرط الأساسي: يجب أن تكون كل محاولة قابلة للدمج من البداية إلى النهاية. يربط معرف الارتباط المشترك (مثل `auth_flow_id`) السياق من جانب العميل بنتيجة تحقق الخادم.

### 11.1 إشارات جانب العميل (SDK للواجهة الأمامية)

| **الإشارة** | **سبب أهميتها** |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `error.name` + مجموعة السبب المطبع | خطأ المتصفح الخام + تصنيفك |
| نوع العملية | واجهة مستخدم مشروطة، تسجيل دخول نمطي، إنشاء يدوي، إنشاء مشروط، إضافة تلقائية. **المصادقة عبر الأجهزة (CDA)** هي وحش معقد بحد ذاته. |
| سياق البيئة الكامل | نظام التشغيل + الإصدار، المتصفح + الإصدار، **العلامة التجارية/طراز الجهاز**، **إعدادات المصادق** (على سبيل المثال، هل تم تمكين GPM؟) |
| سياق المصادق / مدير بيانات الاعتماد | كسر الامتداد والمزود |
| وقت الخطأ من بداية العملية | رفض فوري (`<1s`) مقابل إلغاء المستخدم (1-15s) مقابل المهلة (30s+) |
| حالة الشبكة / الاتصال | غالباً ما تظهر أخطاء الشبكة كأخطاء للعميل. تتبع ما إذا كان المستخدم غير متصل بالإنترنت و**ضع السجلات في قائمة الانتظار** لإرسالها عند استعادة الاتصال. |
| ما إذا ظهرت واجهة الاستجابة السريعة (QR) / الهجينة | الفشل المحلي مقابل فشل عبر الأجهزة |
| معرف الارتباط (`auth_flow_id`) | الانضمام إلى سجلات الخادم |

### 11.2 إشارات جانب الخادم (التحقق من النهاية الخلفية)

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

| **الإشارة** | **سبب أهميتها** |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| عدم تطابق التحدي / تحدي منتهي الصلاحية | مشاكل توقيت الجلسة أو إعادة التشغيل |
| عدم تطابق الأصل / معرف RP | أخطاء تكوين متعددة المجالات |
| توقيع غير صالح / لم يتم العثور على بيانات اعتماد | بيانات اعتماد محذوفة أو تالفة. الحالة الشائعة: تسجيل الدخول بواجهة مستخدم مشروطة باستخدام مفتاح مرور قام المستخدم بالفعل بحذفه من جانب الخادم. استخدم واجهة برمجة تطبيقات الإشارة للحفاظ على مزامنة قوائم بيانات اعتماد العميل والخادم. |
| عدم تطابق مقبض المستخدم | مشاكل تعيين الحساب |
| معرف الارتباط (`auth_flow_id`) | الانضمام إلى سياق جانب العميل |

إذا كنت تريد نموذج قمع كامل (الانقطاعات حسب الخطوة والتحويل بين الخطوات)، راجع: بيانات القياس عن بُعد لمفتاح المرور لفهم الانقطاعات.

[Watch on YouTube](https://www.youtube.com/watch?v=wnrXJzvBjsU)

ومع وجود هذه البيانات في مكانها الصحيح، يصبح الاستنتاج بسيطاً: تصبح معظم "الأخطاء" إما إصلاحات لتجربة المستخدم، أو إصلاحات للتغطية، أو إصلاحات للتكوين. ولكن بناء هذا التصنيف والحفاظ عليه بنفسك هو عمل مستمر كبير.

## 12. ما وراء أسماء الأخطاء: كيف تحول Corbado الأخطاء الخام إلى إشارات قابلة للتنفيذ

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

### 12.1 لماذا لا يكفي `error.name` وحده

يمكن أن يعني `NotAllowedError` نفسه ستة أشياء مختلفة اعتماداً على ثلاثة أبعاد لا تفصلها المتصفحات لك:

| **البعد** | **ما تعطيك إياه المتصفحات** | **ما تحتاجه بالفعل** | **مثال** |
| ---------------------------- | -------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **سياق العملية** | `NotAllowedError` | هل كانت واجهة مستخدم مشروطة، أو تسجيل دخول نمطي، أو إنشاء يدوي، أو إنشاء مشروط، أو إضافة تلقائية؟ | يعرض Android نفس الخطأ "غير معروف" لرفض تسجيل الدخول (متوقع) وفشل الإنشاء (غير متوقع) |
| **التوقيت** | لا توجد بيانات مدة | رفض فوري (`<1s`) مقابل إلغاء المستخدم (1-15 ثانية) مقابل مهلة (30 ثانية فما فوق) | 200 مللي ثانية = رفض البيئة؛ 5 ثوانٍ = رأى المستخدم مربع الحوار وألغى؛ 35 ثانية = مهلة |
| **النظام الأساسي + المصادق** | `error.name` عام | نظام التشغيل، والمتصفح، والإصدار، ومدير بيانات الاعتماد لكل خطأ | يظهر كل من "رفض المستخدم لمربع الحوار" على Chrome و "الملء التلقائي غير متاح" على Safari كـ `NotAllowedError` |

### 12.2 ما تلتقطه حزمة تطوير برامج المراقبة (SDK) لـ Corbado

هذه هي المشكلة التي تم تصميم [حزمة أدوات المراقبة من Corbado](https://www.corbado.com/pricing) لحلها. إنها تكامل واجهة أمامية خفيف الوزن يجلس أعلى تطبيق مفتاح المرور الحالي الخاص بك، ويعمل مع أي خادم WebAuthn وأي موفر هوية (IDP)، ويصنف كل خطأ WebAuthn عبر الأبعاد الثلاثة تلقائياً:

| **القدرة** | **ما يفعله** |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **إسناد الخطأ** | يلتقط نظام التشغيل، وإصدار نظام التشغيل، والمتصفح، وإصدار المتصفح، والمصادق مع كل محاولة حفل |
| **وضع العملية** | يربط كل خطأ بالعملية المحددة (واجهة المستخدم المشروطة، تسجيل الدخول النمطي، الإنشاء اليدوي، الإنشاء المشروط، الإضافة التلقائية) بحيث يحل نفس `NotAllowedError` للأسباب الجذرية المختلفة |
| **التوقيت من بداية الإجراء** | يسجل المدة من بدء الحفل للتمييز بين الرفض الفوري، وإلغاءات المستخدم، والمهلات دون التخمين |
| **التصنيف الذكي للأخطاء** | يتطابق مع سياق الخطأ الكامل (وليس الاسم فقط)، ويقوم بالتطبيع عبر **بيئات** متنوعة (نظام التشغيل، والأجهزة، والإعدادات). يعطي الأولوية لمجموعات الأخطاء المميزة مثل **CDA** مقابل الأخطاء المحلية، ويميز الأخطاء **المتوقعة (إلغاء المستخدم)** عن الأخطاء **غير المتوقعة (فشل النظام)**. |
| **تجزئة مدير كلمات المرور** | يكتشف متى تعترض إضافات مدير الاعتماد (Bitwarden, 1Password, LastPass) الاحتفالات وتعيد استجابات غير قياسية، ويفصل الإخفاقات التي تسببها الإضافات عن إخفاقات المنصة |

هذه هي طبقة **المراقبة (Observe)**: الرؤية لما يحدث، دون تغيير تنفيذك.

### 12.3 طريقتان لتصحيح الأخطاء: من أعلى إلى أسفل ومن أسفل إلى أعلى

تدعم وحدة تحكم الإدارة في Corbado مسارين للتحقيق:

**من أعلى إلى أسفل (لوحة القيادة إلى السبب الجذري):**

1. **مراقبة نوعين متميزين من الشذوذ:**
    - **زيادة الأخطاء المتوقعة (انحراف الخط الأساسي):** هل شهدت بيئة معينة (مثل نظام التشغيل iOS 18.2 على جهاز iPhone 15) زيادة تدريجية في "إلغاءات المستخدم"؟ يشير هذا غالباً إلى احتكاك في تجربة المستخدم ناتج عن تحديث لنظام التشغيل.
    - **زيادة الأخطاء غير المتوقعة (طفرات):** خطأ جديد تماماً أو قفزة مفاجئة في الإخفاقات. يشير هذا عادةً إلى تغيير جذري (تحديث مكدس IDP داخلي) أو تراجع في إصدار متصفح جديد.
2. **تحديد الأولويات حسب التأثير:**
    - **P1: مشاكل تسجيل الدخول.** إذا انخفضت معدلات نجاح تسجيل الدخول، فقم بالتنبيه على الفور.
    - **P2: مشاكل الإنشاء.** راقب الاتجاهات، ولكن تجنب إيقاظ المهندسين بسبب ارتفاع "إلغاء المستخدم" في تدفقات الإنشاء.
3. **التنقل داخل البيئة:** استخدم الأبعاد الحبيبية (الأجهزة، وإعدادات المصادقة) لعزل ما إذا كانت المشكلة عالمية أم خاصة بـ "أجهزة Samsung التي تعمل بنظام Android 14".
4. **التخفيف من الآثار:** في حالة اكتشاف ارتفاع حرج، اجعل **مفتاح الإيقاف (Kill Switch)** جاهزاً. قم بتعطيل مفاتيح المرور تلقائياً أو يدوياً لتلك البيئة المحددة واستخدم كلمات المرور لمرة واحدة / كلمات المرور كاحتياطي للحفاظ على معدلات تسجيل الدخول أثناء التحقيق.

**من أسفل إلى أعلى (أنماط الأخطاء إلى التأثير):**

1. ابدأ من طريقة عرض تصنيف الأخطاء. راجع أنماط الأخطاء المصنفة وأحجامها.
2. قم بتحسين خرائط الأخطاء مع ظهور أنماط جديدة (على سبيل المثال، إصدار متصفح جديد يشحن رسالة خطأ مختلفة).
3. يتم ربط الأخطاء بالتغييرات في مؤشرات الأداء الرئيسية (KPIs) ويتم إظهارها كتعليقات توضيحية على لوحات المعلومات، بحيث يتم ربط أي ارتفاع في نمط خطأ معين تلقائياً بالمقياس الذي أثر عليه.

كلا المسارين يتقاربان: من أعلى إلى أسفل يخبرك بأن هناك خطأ ما، ومن أسفل إلى أعلى يخبرك بالسبب. يربط [مساعد تحليلات الذكاء الاصطناعي (AI Analytics Assistant)](https://www.corbado.com/ai-analytics-assistant) بين الاثنين من خلال السماح لك بطرح أسئلة باللغة الطبيعية عبر كل من بيانات الخطأ ومقاييس التبني.

بالنسبة للفرق التي ترغب في التصرف بناءً على هذه الإشارات، يمكنها الانتقال إلى **التبني (Adopt)**، الذي يضيف [ذكاء مفتاح المرور](https://docs.corbado.com/corbado-connect/features/passkey-intelligence) إلى الاحتفالات التلقائية، وتحسين مطالبات التسجيل، ومعالجة حالات مفتاح المرور المعطلة. بالنسبة للبيئات المنظمة أو عمليات النشر على نطاق واسع، يضيف **المؤسسات (Enterprise)** استضافة المستأجر الفردي، وتكامل SIEM، والتكوين المتوافق مع PSD2.

## 13. الخاتمة

أسماء أخطاء WebAuthn ليست حكماً. إنها تلميحات - وتصبح قابلة للتنفيذ فقط عند ربطها بنوع العملية والتوقيت وسياق النظام الأساسي.

- **ماذا تعني أسماء أخطاء WebAuthn الأكثر شيوعاً في الإنتاج؟** معظمها يتوافق مع مجموعة صغيرة من الطبقات: التحكم في تدفق المستخدم (`NotAllowedError`)، ودورة حياة التطبيق / التزامن (`AbortError`)، وسياق الأمان / التكوين (`SecurityError`)، أو أخطاء الخيار / الحالة (`InvalidStateError`, `ConstraintError`, `DataError`). الغالبية العظمى من الحجم هو `NotAllowedError`، ومعظم هذا السلوك متوقع (رفض المستخدم للمطالبة).
- **كيف تميز `NotAllowedError`؟** استخدم التوقيت (الرفض الفوري مقابل إلغاء المستخدم مقابل المهلة)، ومؤشر الاستجابة السريعة / الهجين (عدم تطابق التوفر)، وسياق تنشيط المستخدم (خاصة على iOS/Safari)، ونوع العملية (واجهة مستخدم مشروطة مقابل تسجيل الدخول النمطي مقابل إنشاء مفتاح مرور مقابل إنشاء مشروط). لا تعامل جميع `NotAllowedError` كوضع فشل واحد.
- **لماذا يهم نوع العملية؟** يمثل `error.name` نفسه أثناء تسجيل الدخول بواجهة مستخدم مشروطة إشارة مختلفة تماماً عما هو عليه أثناء الإنشاء المشروط أو الإنشاء اليدوي لمفتاح المرور (رفض المستخدم لمربع الحوار). تسجيل نوع العملية بجانب الخطأ هو ما يحول `NotAllowedError` العام إلى دلو قابل للتنفيذ.
- **ما هو الحد الأدنى من السياق الذي يجعل الأخطاء قابلة للتصحيح؟** التقاط `error.name`، ونوع العملية، ووقت الخطأ من بداية العملية، ونوع التدفق، وما إذا تم عرض واجهة مستخدم الاستجابة السريعة / الهجينة، ونظام التشغيل/المتصفح/الجهاز (بما في ذلك الإصدارات)، ومعرف الارتباط (`auth_flow_id`) ورفض تحقق الخادم كرموز صريحة.

هناك قاعدتان عامتان تتقاطعان مع جميع أنواع الأخطاء: لا تعرض أبداً أخطاء المتصفح الخام للمستخدمين - قم دائماً بتوفير مسار احتياطي واضح - وافصل المحاولات المحلية عن المحاولات الهجينة/الاستجابة السريعة (QR) عبر الأجهزة، لأنها تفشل لأسباب مختلفة وتحتاج إلى إصلاحات مختلفة. على نطاق واسع، يعد الحفاظ على تصنيف الأخطاء عبر المتصفحات وإصدارات نظام التشغيل ومديري كلمات المرور عملاً مستمراً. فكر في استخدام حزمة أدوات تطوير للمراقبة (SDK) مع مكتبة أنماط مُدارة بدلاً من بناء ذلك من الصفر.

## الأسئلة المتداولة

### كيف يمكنني معرفة الفرق بين إلغاء المستخدم لمطالبة مفتاح المرور وعدم وجود مفتاح مرور على الجهاز؟

على الويب، تدمج المتصفحات كلتا الحالتين في `NotAllowedError` لأسباب تتعلق بالخصوصية، لذا لا يمكنك التمييز بينهما مباشرة. استخدم التوقيت كبديل: الخطأ تحت ثانية واحدة يعني عادةً رفض البيئة أو عدم توفر الإمكانية، بينما 1-15 ثانية تشير إلى أن المستخدم رأى مربع الحوار وتجاهله. في تطبيقات iOS و Android الأصلية، يوفر تعيين `preferImmediatelyAvailableCredentials` قبل الطلب إشارة "لا توجد بيانات اعتماد" واضحة (رمز iOS 1005، و `GetCredentialRequest` في Android) قبل عرض أي واجهة مستخدم.

### لماذا معدل أخطاء WebAuthn لدي مرتفع للغاية على الرغم من أن مفاتيح المرور تبدو وكأنها تعمل مع معظم المستخدمين؟

في عمليات نشر مفتاح المرور المحسّنة واسعة النطاق، أكثر من 95٪ من أخطاء WebAuthn المسجلة هي إحباطات متوقعة من قبل المستخدم، وليست إخفاقات في النظام. إن تتبع أعداد `error.name` الأولية دون فصل "مربع حوار رفضه المستخدم" عن الإخفاقات الحقيقية يؤدي إلى تضخيم مقاييس الخطأ ويخفي التراجعات الحقيقية المخفية داخل حجم `NotAllowedError`. قسّم أعدادك حسب نوع العملية وتعامل مع دلاء إلغاء المستخدم بشكل منفصل عن الأخطاء غير المتوقعة مثل `SecurityError` و `ConstraintError` و `DataError`.

### ماذا يعني رمز ASAuthorizationError 1005 على نظام iOS وكيف يجب أن أستخدمه؟

يعني رمز iOS 1005 (`NotInteractive`) أنه لا يوجد مفتاح مرور متاح على الجهاز عند تعيين `preferImmediatelyAvailableCredentials` على `ASAuthorizationController`، ولم يتم عرض واجهة مستخدم للمستخدم. هذه هي إشارة "لا يوجد مفتاح مرور على هذا الجهاز" النظيفة التي لا تستطيع متصفحات الويب توفيرها بسبب قيود الخصوصية. صنف دائماً بناءً على الرمز الرقمي، وليس على `localizedDescription`، لأن رسائل Apple مترجمة إلى أكثر من 30 لغة ويمكن أن تتغير عبر إصدارات نظام التشغيل.

### كيف يجب أن أتعامل مع NotAllowedError أثناء تدفق إنشاء مشروط أو إضافة مفتاح مرور يتم تشغيله تلقائياً؟

أثناء الإنشاء المشروط، تُعد الأخطاء `NotAllowedError` و `AbortError` و `InvalidStateError` نتائج متوقعة ويجب تجاهلها بصمت بدلاً من ظهورها كأخطاء. يشير `NotAllowedError` إلى أن الملء التلقائي غير متاح أو أن الصفحة فقدت التركيز، بينما يعني `InvalidStateError` أن مفتاح المرور موجود بالفعل في المزود. قبل محاولة الاتصال، استخدم `getClientCapabilities()` للتحقق من دعم `conditionalCreate` والتحقق من حالة رؤية المستند لتجنب تضخيم عدد الأخطاء.

### ما هو السياق الذي يجب أن أسجله جنباً إلى جنب مع error.name لجعل أخطاء WebAuthn قابلة للتصحيح فعلياً؟

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