تجربة المستخدم عند أخطاء قيود قاعدة البيانات: حوّل الفشل إلى رسائل واضحة
تعلم كيف تتحوّل أخطاء قيود قاعدة البيانات إلى رسائل مفيدة على مستوى الحقول عبر ربط حالات الفشل الفريدة، المفتاح الخارجي، وNOT NULL في تطبيقك.

لماذا تبدو حالات فشل القيود مزعجة للمستخدمين؟
عندما يضغط المستخدم على حفظ، يتوقع نتيجة من اثنتين: نجحت العملية، أو يمكنه إصلاح ما لم ينجح بسرعة. في كثير من الأحيان يحصل على لافتة عامة مثل “فشل الطلب” أو “حدث خطأ ما.” يبقى النموذج كما هو، ولا يتم تمييز أي شيء، ويُترك المستخدم للتخمين.
هذا الفرق هو سبب أهمية تحسين تجربة المستخدم عند أخطاء قيود قاعدة البيانات. قاعدة البيانات تفرض قواعد لم يرها المستخدم: “يجب أن تكون هذه القيمة فريدة”، “يجب أن يشير هذا السجل إلى عنصر موجود”، “لا يجوز أن يكون هذا الحقل فارغًا”. إذا أخفى التطبيق هذه القواعد خلف خطأ غامض، يشعر الناس باللوم لمشكلة لا يفهمونها.
الأخطاء العامة تقوّض الثقة أيضًا. يفترض الناس أن التطبيق غير مستقر، فيعيدون المحاولة أو يعيدون التحميل أو يتخلون عن المهمة. في بيئة عمل، يرسلون لقطات شاشة للدعم لا تساعد، لأن لقطة الشاشة لا تحمل تفصيلاً مفيدًا.
مثال شائع: ينشئ شخص سجل عميل ويحصل على “فشل الحفظ.” يحاول مرة أخرى بنفس البريد الإلكتروني. يفشل مجددًا. الآن يتساءل هل النظام يكرر البيانات، يفقدها، أم كلاهما.
قاعدة البيانات غالبًا ما تكون مصدر الحقيقة النهائي، حتى لو تحققت الواجهة مقدمًا. ترى أحدث الحالة، بما في ذلك تغييرات من مستخدمين آخرين، وظائف خلفية وتكاملات. لذلك ستحدث حالات فشل القيود، وهذا طبيعي.
النتيجة الجيدة بسيطة: حوّل قاعدة بيانات أو قاعدة منطق إلى رسالة تشير إلى حقل محدد وخطوة تالية. على سبيل المثال:
- “البريد الإلكتروني مستخدم بالفعل. جرّب بريدًا آخر أو سجّل الدخول.”
- “اختر حسابًا صالحًا. الحساب المحدد لم يعد موجودًا.”
- “رقم الهاتف مطلوب.”
بقية المقال تتناول كيفية إجراء تلك الترجمة، حتى تتحول حالات الفشل إلى استرداد سريع، سواء كتبت الواجهة الخلفية بنفسك أو بنتها بأداة مثل AppMaster (appmaster.io).
أنواع القيود التي ستواجهها (وماذا تعني)
معظم لحظات “فشل الطلب” تأتي من مجموعة صغيرة من قواعد قاعدة البيانات. إذا استطعت تسمية القاعدة، يمكنك عادة تحويلها إلى رسالة واضحة على الحقل الصحيح.
إليك أنواع القيود الشائعة بلغة بسيطة:
- قيد فريد (Unique constraint): يجب أن تكون القيمة فريدة. أمثلة نموذجية هي البريد الإلكتروني، اسم المستخدم، رقم الفاتورة، أو معرف خارجي. عند الفشل، لم “يفعل المستخدم شيئًا خاطئًا” بالضرورة؛ بل تعارضت القيمة مع بيانات موجودة.
- قيد المفتاح الخارجي (Foreign key constraint): يشير سجل إلى سجل آخر يجب أن يكون موجودًا (مثل
order.customer_id). يفشل عندما تم حذف المرجع، لم يكن موجودًا أصلًا، أو أرسلت الواجهة معرفًا خاطئًا. - قيد NOT NULL: قيمة مطلوبة مفقودة على مستوى قاعدة البيانات. قد يحدث هذا حتى لو بدا النموذج مكتملًا (مثلاً، الواجهة لم ترسل الحقل، أو الـ API استبدله).
- قيد Check: القيمة خارجة عن قاعدة مسموح بها، مثل “يجب أن تكون الكمية \u003e 0”، “الحالة يجب أن تكون من بين هذه القيم”، أو “الخصم يجب أن يكون بين 0 و100.”
المشكلة المعقّدة أن نفس المشكلة الواقعية قد تظهر بشكل مختلف حسب قاعدة البيانات والأدوات. قد تسمي Postgres القيد (مفيد)، بينما قد يلفه ORM في استثناء عام (غير مفيد). حتى القيد الفريد نفسه قد يظهر كـ “duplicate key”، “unique violation”، أو كود خطأ خاص بالبائع.
مثال عملي: يحرر شخص عميلًا في لوحة المشرف، يضغط حفظ، ويحصل على فشل. إذا استطاع الـ API إخبار الواجهة أنه كان قيدًا فريدًا على email، يمكنك عرض “هذا البريد مستخدم بالفعل” تحت حقل البريد بدلاً من إشعار غامض.
عامل كل نوع قيد كدليل عن ما يمكن للمستخدم فعله تاليًا: اختر قيمة مختلفة، اختر سجلًا مرتبطًا موجودًا، أو املأ الحقل المطلوب.
ماذا يجب أن تفعل رسالة جيدة على مستوى الحقل؟
فشل قيد قاعدة البيانات حدث تقني، لكن يجب أن تبدو التجربة كإرشاد عادي. تحول رسائل أخطاء القيود الجيدة “حدث خطأ ما” إلى “إليك ما يجب إصلاحه” دون إجبار المستخدم على التخمين.
استخدم لغة بسيطة. استبدل كلمات قواعد البيانات مثل “unique index” أو “foreign key” بشيء يفهمه الإنسان. “هذا البريد مستخدم بالفعل” أكثر إفادة بكثير من “duplicate key value violates unique constraint.”
ضع الرسالة حيث الفعل. إذا كان الخطأ يعود لحقل واحد، أرفقه بذلك الحقل حتى يصلح المستخدم الأمر فورًا. إذا كان عن الإجراء ككل (مثل “لا يمكنك الحذف لأنه مستخدم في مكان آخر”) أظهره على مستوى النموذج مع خطوة تالية واضحة.
الرسائل المحددة أفضل من الرسائل المهذبة. رسالة مفيدة تجيب على سؤالين: ما الذي يجب تغييره، ولماذا رُفض. “اختر اسم مستخدم مختلف” أفضل من “اسم المستخدم غير صالح.” “اختر عميلًا قبل الحفظ” أفضل من “بيانات مفقودة.”
كن حذرًا من التفاصيل الحساسة. أحيانًا أكثر رسالة “مفيدة” تكشف معلومات. في شاشة تسجيل الدخول أو إعادة تعيين كلمة المرور، قد يساعد قول “لا يوجد حساب لهذا البريد” المهاجمين. في هذه الحالات استخدم رسالة أكثر أمانًا مثل “إذا كان هناك حساب يطابق هذا البريد ستصلك رسالة قريبًا.”
خطط أيضًا لأكثر من مشكلة في وقت واحد. قد يفشل حفظ واحد على عدة قيود. يجب أن تعرض الواجهة عدة رسائل حقول معًا دون إرباك الشاشة.
رسالة قوية على مستوى الحقل تستخدم كلمات بسيطة، تشير إلى الحقل المناسب (أو تكون بوضوح رسالة نموذجية)، تخبر المستخدم ماذا يغيّر، تتجنب كشف حقائق خاصة عن الحسابات أو السجلات، وتدعم تعدد الأخطاء في استجابة واحدة.
صمّم عقد أخطاء بين الـ API والواجهة
تبدأ تجربة المستخدم الجيدة باتفاق: عندما يحدث فشل، يخبر الـ API الواجهة بما حدث بالضبط، وتعرض الواجهة ذلك بنفس الطريقة دائمًا. بدون هذا العقد، تعود إلى لافتة غامضة لا تفيد أحدًا.
شكل خطأ عملي يكون صغيرًا لكن محددًا. يجب أن يحمل رمز خطأ ثابت، الحقل (عندما يتعلق بحقل واحد)، رسالة بشرية، وتفاصيل اختيارية للتسجيل.
{
"error": {
"code": "UNIQUE_VIOLATION",
"field": "email",
"message": "That email is already in use.",
"details": {
"constraint": "users_email_key",
"table": "users"
}
}
}
المهم هو الثبات. لا تعرض نصوص قاعدة البيانات الخام للمستخدمين، ولا تجعل الواجهة تُحلّل رسائل Postgres. يجب أن تكون الرموز متسقة عبر المنصات (ويب، iOS، Android) وعبر النهايات.
قرّر مسبقًا كيف تمثل أخطاء الحقول مقابل أخطاء النموذج. خطأ حقل يعني أن إدخالًا واحدًا محظور (عيّن field، اعرض الرسالة تحت الإدخال). خطأ على مستوى النموذج يعني أن الإجراء لا يمكن إتمامه رغم أن الحقول تبدو صحيحة (اترك field فارغًا، وأظهر الرسالة قرب زر الحفظ). إذا كان بإمكان عدة حقول أن تفشل معًا، أعد مصفوفة من الأخطاء، كل واحدة مع field وcode خاصين بها.
للحفاظ على عرض متسق، اجعل قواعد العرض مملة ومتوقعة: اعرض الخطأ الأول قرب الأعلى كملخص قصير وبصورة مضمنة بجوار الحقل، اجعل الرسائل قصيرة وقابلة للتنفيذ، أعد استخدام نفس الصياغة عبر المسارات (التسجيل، تعديل الملف، شاشات المشرف)، وسجّل details بينما تعرض فقط message.
إذا بنيت مع AppMaster، عامل هذا العقد مثل أي إخراج API آخر. يمكن لواجهتك الخلفية إرجاع الشكل المهيكل، ويمكن لتطبيقات الويب (Vue3) والمحمول المولّدة عرضه بنمط مشترك، بحيث يشعر كل فشل قيد بالإرشاد وليس بالتحطّم.
خطوة بخطوة: ترجمة أخطاء قاعدة البيانات إلى رسائل حقول
تحسين تجربة أخطاء القيود يبدأ باعتبار قاعدة البيانات الحكم النهائي، لا خط الدفاع الأول. يجب ألا يرى المستخدمون نص SQL خامًا، تتبعات المكدس، أو “فشل الطلب” الغامض. يجب أن يروا الحقل الذي يحتاج انتباهًا وما يفعلونه بعد ذلك.
تدفق عملي يعمل في معظم البُنى:
- قرّر أين تُلتقط الأخطاء. اختَر مكانًا واحدًا حيث تصبح أخطاء قاعدة البيانات استجابات API (غالبًا طبقة المستودع/DAO أو معالج أخطاء عام). هذا يمنع حالة “أحيانًا مضمن، أحيانًا لافتة”.
- صنّف الفشل. عندما يفشل كتابة، اكتشف الفئة: قيد فريد، مفتاح خارجي، NOT NULL، أو قيد Check. استخدم أكواد أخطاء السائق متى أمكن. تجنّب تحليل النصوص البشرية إلا إذا لم يكن هناك خيار.
- طابِق أسماء القيود بمفاتيح حقول النموذج. القيود معرّفات رائعة، لكن الواجهات تحتاج مفاتيح حقول. احتفظ ببحث بسيط مثل
users_email_key -> emailأوorders_customer_id_fkey -> customerId. ضعه بالقرب من الكود الذي يملك المخطط. - ولّد رسالة آمنة. كوّن نصًا قصيرًا وصديقًا للمستخدم بحسب الفئة، لا بحسب رسالة قاعدة البيانات الخام. فريد -> “هذه القيمة مستخدمة بالفعل.” مفتاح خارجي -> “اختر عميلًا موجودًا.” NOT NULL -> “هذا الحقل مطلوب.” Check -> “القيمة خارج النطاق المسموح.”
- أعد أخطاء مهيكلة وعرّضها مضمنًا. أرسل حمولة متسقة (مثال:
[{ field, code, message }]). في الواجهة، أرفق الرسائل بالحقول، مرّر وركّز أول حقل فاشل، واترك أي لافتة عامة كملخص فقط.
إذا بنيت مع AppMaster، طبّق نفس الفكرة: التقط خطأ قاعدة البيانات في مكان واحد بالواجهة الخلفية، ترجمه إلى شكل خطأ حقل قابل للتنبؤ، ثم أظهره بجوار الإدخال في واجهة الويب أو الجوال المولّدة. هذا يحافظ على اتساق التجربة حتى مع تطور نموذج البيانات.
مثال واقعي: ثلاث عمليات حفظ فشلت، ثلاث نتائج مفيدة
غالبًا ما تُطوى هذه الفشلات كلها في لافتة مبهمة واحدة. كل واحدة تحتاج رسالة مختلفة، رغم أنها جميعًا تأتي من قاعدة البيانات.
1) التسجيل: البريد مستخدم بالفعل (قيد فريد)
الفشل الخام (ما قد تراه في السجلات): duplicate key value violates unique constraint "users_email_key"
ما يجب أن يراه المستخدم: “هذا البريد مسجّل بالفعل. جرّب تسجيل الدخول، أو استخدم بريدًا آخر.”
ضع الرسالة بجوار حقل البريد واحتفظ بما في النموذج. إن أمكن، قدّم إجراء ثانوي مثل “تسجيل الدخول” حتى لا يضطر المستخدم للتخمين.
2) إنشاء طلب: العميل مفقود (مفتاح خارجي)
الفشل الخام: insert or update on table "orders" violates foreign key constraint "orders_customer_id_fkey"
ما يجب أن يراه المستخدم: “اختر عميلًا لوضع هذا الطلب.”
هذا لا يبدو كـ"خطأ" للمستخدم بقدر ما يبدو كالسياق المفقود. ظلّل محدد العميل، احتفظ بأي عناصر سطر أضافها المستخدم، وإذا حُذف العميل في تبويب آخر فقل ذلك بوضوح: “ذلك العميل لم يعد موجودًا. اختر آخر.”
3) تحديث الملف الشخصي: حقل مطلوب مفقود (NOT NULL)
الفشل الخام: null value in column "last_name" violates not-null constraint
ما يجب أن يراه المستخدم: “الاسم الأخير مطلوب.”
هكذا يبدو التعامل الجيد مع القيود: ملاحظات نموذج عادية، ليس فشل نظام.
للمساعدة في الدعم دون تسريب تفاصيل تقنية، احتفظ بالخطأ الكامل في السجلات (أو لوحة أخطاء داخلية): تضمين معرّف الطلب والجلوس/المستخدم، اسم القيد (إن وُجد) والطاولة/الحقل، حمولة الطلب (مع إخفاء الحقول الحساسة)، الطابع الزمني والنقطة النهاية، ورسالة وجه المستخدم التي عُرضت.
أخطاء المفتاح الخارجي: ساعد المستخدم على التعافي
فشلات المفتاح الخارجي غالبًا تعني أن المستخدم اختار شيئًا لم يعد موجودًا، أو لم يعد مسموحًا به، أو لا يتطابق مع القواعد الحالية. الهدف ليس فقط شرح الفشل، بل إعطاء خطوة تالية واضحة.
غالبًا ما يربط فشل المفتاح الخارجي بحقل واحد: عنصر الاختيار الذي يشير إلى سجل آخر (Customer, Project, Assignee). يجب أن تسمّي الرسالة بالشيء الذي يتعرف عليه المستخدم، لا بمفهوم قاعدة البيانات الداخلية. تجنّب المعرفات الداخلية أو أسماء الجداول. “العميل لم يعد موجودًا” مفيد. “FK_orders_customer_id violated (customer_id=42)” ليس كذلك.
نمط تعافٍ قوي يعامل الخطأ كاختيار قديم. اطلب من المستخدم إعادة الاختيار من أحدث قائمة (تحديث القائمة المنسدلة أو فتح منتقي البحث). إذا حُذف السجل أو أُؤرشف، قل ذلك بصراحة ووجّههم إلى بديل نشط. إذا فقد المستخدم الأذونات، قل “لم يعد لديك إذن لاستخدام هذا العنصر” واطلب منه اختيار آخر أو التواصل مع مسؤول.
سجلات محذوفة أو مؤرشفة فخ شائع. إذا كانت واجهتك تستطيع إظهار العناصر غير النشطة للسياق، وسمّها بوضوح (Archived) ومنع اختيارها. هذا يمنع الفشل، لكنه لا يزال يتعامل مع الحالة عندما يغيّر مستخدم آخر البيانات.
أحيانًا يجب أن يكون فشل المفتاح الخارجي على مستوى النموذج، لا الحقل. افعل ذلك عندما لا يمكنك تحديد المرجع المسبب بدقة، عندما تكون عدة مراجع غير صالحة، أو عندما تكون المشكلة الحقيقية أذونات عبر الإجراء بأكمله.
NOT NULL والتحقق: امنع الخطأ، وتعامل معه إن حدث
فشلات NOT NULL الأسهل منعًا والأكثر إزعاجًا عند تسربها. إذا رأى المستخدم “فشل الطلب” بعد ترك حقل مطلوب فارغًا، فقاعدة البيانات تقوم بعمل واجهة المستخدم. جيد أن تمنع الواجهة الحالات الواضحة، والـ API يجب أن يعيد أخطاء حقلية واضحة عندما يفوت شيء.
ابدأ بالتحققات المبكرة في النموذج. علّم الحقول المطلوبة مباشرة قرب الإدخال، ليس في لافتة عامة. تلميح قصير مثل “مطلوب من أجل الإيصالات” أكثر إفادة من نجمة حمراء فقط. إذا كان الحقل مطلوبًا شرطياً (مثلاً، “اسم الشركة” فقط عند “نوع الحساب = Business”)، اجعل القاعدة مرئية عند لحظة الصلة.
التحقق في الواجهة لا يكفي. يمكن للمستخدم تجاوزه بإصدارات تطبيق قديمة، شبكات متقطعة، استيرادات جماعية، أو أتمتة. كرر نفس القواعد في الـ API حتى لا تضيّع رحلة وإرجاع دور لأن القاعدة فشلت لاحقًا.
حافظ على تناسق الصياغة عبر التطبيق حتى يتعلم الناس ما تعنيه كل رسالة. للقيم المفقودة استخدم “مطلوب.” لحدود الطول استخدم “طويل جدًا (الحد الأقصى 50 حرفًا).” لفحوص الصيغة استخدم “تنسيق غير صالح (استخدم [email protected]).” لمشاكل النوع استخدم “يجب أن يكون رقمًا.”
التحديثات الجزئية هي حيث يصبح NOT NULL معقّدًا. لا ينبغي أن يفشل PATCH يحذف حقلًا مطلوبًا إذا كانت القيمة الحالية موجودة بالفعل، لكن يجب أن يفشل إذا حدّد العميل صراحةً قيمة null أو قيمة فارغة. قرّر هذه القاعدة مرة واحدة، وثقّفها، وطبّقها باستمرار.
نهج عملي هو التحقق على ثلاث طبقات: قواعد نموذج العميل، تحقق طلب الـ API، وشبّاك أمان نهائي يلتقط خطأ NOT NULL من قاعدة البيانات ويربطه بالحقل الصحيح.
أخطاء شائعة تعيد إلى “فشل الطلب”
الطريقة الأسرع لإفساد التعامل مع القيود هي أن تفعل كل العمل الصعب في قاعدة البيانات، ثم تخفي النتيجة خلف لافتة عامة. المستخدمون لا يهتمون أن قيدًا حدث؛ يهتمون بما يصلحونه، أين، وهل بياناتهم آمنة.
خطيئة شائعة هي عرض نص قاعدة البيانات الخام. رسائل مثل duplicate key value violates unique constraint تبدو كسقوط كامل، حتى عندما يمكن للتطبيق التعافي. كما أنها تولّد تذاكر دعم لأن المستخدمين ينسخون نصًا مخيفًا بدلًا من تصحيح حقل واحد.
فخ آخر هو الاعتماد على مطابقة السلاسل. تعمل حتى تغيّر السائق، ترقي Postgres، أو تعيد تسمية قيدًا. حينها يتوقف التعيين “البريد مستخدم” بصمت، وتعود إلى “فشل الطلب.” فضّل أكواد أخطاء مستقرة وضمّن اسم الحقل الذي تفهمه الواجهة.
التغييرات في المخطط تكسر تعيين الحقول أكثر مما يتوقع الناس. إعادة تسمية من email إلى primary_email يمكن أن تحوّل رسالة واضحة إلى بيانات بلا مكان عرض. اجعل التعيين جزءًا من نفس مجموعة التغييرات مع الهجرة، وافشل بصوت عالٍ في الاختبارات إذا كان مفتاح الحقل مجهولًا.
قاتل تجربة المستخدم الكبير هو تحويل كل فشل قيد إلى HTTP 500 بلا جسم. هذا يقول للواجهة “هذا خطأ الخادم”، فلا يمكنها عرض تلميحات على الحقول. معظم فشلات القيود قابلة للتصحيح من قبل المستخدم، لذا أعد استجابة بطراز تحقق تتضمن تفاصيل.
بعض الأنماط التي راقبها:
- رسائل البريد الفريد التي تؤكد وجود حساب (استخدم صياغة محايدة في شاشات التسجيل)
- التعامل مع “خطأ واحد في كل مرة” وإخفاء الحقل الثاني المعطوب
- النماذج متعددة الخطوات التي تفقد الأخطاء بعد التنقّل للوراء/أمام
- المحاولات المتكررة التي تُرسل قيمًا قديمة وتُلغِي رسالة الحقل الصحيحة
- السجلات التي تُسقط اسم القيد أو كود الخطأ، مما يصعّب تتبّع الأخطاء
على سبيل المثال، إذا قال نموذج التسجيل “البريد موجود بالفعل”، قد تكون قد سربت وجود حساب. رسالة أكثر أمانًا هي “تحقق من بريدك أو جرّب تسجيل الدخول”، مع إرفاق الخطأ بحقل البريد.
قائمة تحقق سريعة قبل الإطلاق
قبل الإطلاق، تحقق من التفاصيل الصغيرة التي تُقرّر ما إذا كان فشل القيد سيشعر كملاحظة مفيدة أم طريق مسدود.
استجابة API: هل يمكن للواجهة فعل شيء بناءً عليها؟
تأكد أن كل فشل على طراز التحقق يعيد بنية كافية للإشارة إلى إدخال محدد. لكل خطأ عُدّ field، code ثابت، وmessage بشري. غطِّ حالات قاعدة البيانات الشائعة (فريد، مفتاح خارجي، NOT NULL، Check). احتفظ بالتفاصيل التقنية للسجلات، ليس للمستخدمين.
سلوك الواجهة: هل يساعد الشخص على التعافي؟
حتى الرسالة المثالية تبدو سيئة إذا قاوم النموذج المستخدم. ركّز أول حقل فاشل ومرره إلى العرض إذا لزم. احتفظ بما كتبه المستخدم (خصوصًا بعد أخطاء متعددة الحقول). اعرض الأخطاء على مستوى الحقل أولًا، مع ملخص قصير فقط عند الحاجة.
السجلات والاختبارات: هل تلتقط الانكسارات؟
تعامل مع معالجة القيود كميزة مُصانة. سجّل خطأ قاعدة البيانات داخليًا (اسم القيد، الجدول، العملية، معرّف الطلب) لكن لا تعرضه مباشرة. أضف اختبارات على الأقل لمثال واحد لكل نوع قيد، وتحقق أن تعيينك يظل ثابتًا حتى لو تغيرت صياغة قاعدة البيانات.
خطوات تالية: اجعلها متسقة في تطبيقك
معظم الفرق تصلح أخطاء القيود شاشة تلو الأخرى. هذا مفيد، لكن المستخدمين يلاحظون الفجوات: نموذج واحد يعرض رسالة واضحة، وآخر ما زال يقول “فشل الطلب.” الاتساق هو ما يحول هذا من رقعة إلى نمط.
ابدأ حيث يؤلم الأمر. استخرج أسبوعًا من السجلات أو تذاكر الدعم واختر القيود القليلة التي تظهر مرارًا. هذه "المسببات الأعلى" يجب أن تكون أول من يحصل على رسائل صديقة على مستوى الحقول.
عامل ترجمة الأخطاء كميزة منتج صغيرة. احتفظ بتعيين مشترك يستخدمه التطبيق كله: اسم القيد (أو الكود) -> اسم الحقل -> الرسالة -> تلميح الاسترداد. اجعل الرسائل بسيطة، والتلميح قابلاً للتنفيذ.
خطة إطلاق خفيفة تناسب دورة منتج مشغولة:
- حدّد 5 قيود يواجهها المستخدمون أكثر واكتب الرسالة الدقيقة التي تريد عرضها.
- أضف جدول تعيين واستخدمه في كل نقطة نهاية تحفظ بيانات.
- عيّن طريقة موحدة لعرض الأخطاء في النماذج (نفس الموضع، نفس النبرة، نفس سلوك التركيز).
- راجع الرسائل مع زميل غير تقني واسأل: “ماذا ستفعل بعد ذلك؟”
- أضف اختبارًا واحدًا لكل نموذج يتحقّق من تمييز الحقل الصحيح وأن الرسالة مقروءة.
إذا أردت بناء هذا السلوك المتسق دون كتابة كل شاشة يدويًا، يدعم AppMaster (appmaster.io) APIs خلفية بالإضافة إلى تطبيقات ويب ومحمول مولّدة. هذا يسهل إعادة استخدام شكل خطأ مهيكل واحد عبر العملاء، حتى تظل ملاحظات الحقول متسقة مع تغيّر نموذج البيانات.
اكتب ملاحظَة قصيرة "أسلوب رسائل الخطأ" لفريقك أيضًا. اجعلها بسيطة: الكلمات التي تتجنّبها (مصطلحات قواعد البيانات)، وما الذي يجب أن تتضمنه كل رسالة (ما حدث، وماذا تفعل بعد ذلك).
الأسئلة الشائعة
عامِلها كتعليقات نموذج عادية، لا كتعطّل في النظام. أظهر رسالة قصيرة قرب الحقل الذي يحتاج تعديلًا، احتفظ بما كتبه المستخدم، وفسّر الخطوة التالية بلغة بسيطة.
خطأ على مستوى الحقل يشير إلى حقل واحد ويخبر المستخدم بما يجب إصلاحه فورًا، مثل “البريد الإلكتروني مستخدم بالفعل.” رسالة عامة تجبر المستخدم على التخمين وإعادة المحاولة والتواصل مع الدعم لأنها لا تبيّن ما يجب تغييره.
استخدم رموز خطأ ثابتة من سائق قاعدة البيانات متى أمكن ثم خرّجها إلى أنواع مستخدمية مثل فريد، مفتاح خارجي، إلزامي، وقواعد النطاق. تجنّب تحليل نصوص قواعد البيانات لأنها تتغير بين السواقات والإصدارات.
احتفظ بخريطة بسيطة من اسم القيد إلى مفتاح حقل واجهة المستخدم في الواجهة الخلفية، قريبة من كود امتلاك المخطط. مثلاً اربط قيد فريد على البريد بـ email حتى يتمكن الواجهة من تمييز الحقل الصحيح دون تخمين.
افترض “هذه القيمة مستخدمة بالفعل” كمجموعة افتراضية وأضف خطوة تالية واضحة مثل “جرّب آخر” أو “سجّل الدخول”، مع صياغة محايدة في شاشات التسجيل أو إعادة تعيين كلمة المرور حتى لا تؤكد وجود حساب.
اشرحها على أنها اختيار قديم أو غير صالح يعرفه المستخدم، مثل “هذا العميل لم يعد موجودًا. اختر آخر.” إذا كان الحل يتطلب إنشاء سجل مرتبط، قدّم رابطًا لإنشاء سجل جديد بدلاً من إعادة المحاولة الفارغة.
علّم الحقول الإلزامية في الواجهة ووفّر تحققًا قبل الإرسال، لكن اعتبر قاعدة البيانات كشبّاك أمان أخير. عند حدوث الخطأ، أظهر رسالة بسيطة “مطلوب” على الحقل واحتفظ بمحتويات النموذج الأخرى.
أعد مصفوفة من الأخطاء، كل واحد منها مع مفتاح الحقل، رمز ثابت ورسالة قصيرة، حتى تعرض الواجهة كل الأخطاء مرة واحدة. في العميل، ركّز على أول حقل فاشل لكن اترك باقي الرسائل مرئية حتى لا يحتبس المستخدم في حل خطأ واحد تلو الآخر.
استخدم حمولة متسقة تفصل ما يراه المستخدم عن ما تُسجّله، مثل رسالة للمستخدم مع تفاصيل داخلية (اسم القيد ومعرّف الطلب). لا تكشف أخطاء SQL الخام للمستخدم ولا تدع الواجهة تحلل نصوص قاعدة البيانات.
ركّز الترجمة في مكان واحد بالخادم، أعد شكل خطأ متوقع واحد، واطبّقه بنفس الطريقة في كل نموذج. مع AppMaster (appmaster.io) يمكنك تطبيق نفس عقدة الخطأ المهيكلة عبر الواجهات المولّدة، ما يحافظ على اتساق الرسائل مع تغيّر نموذج البيانات.


