← تعلّم

استكشاف الأخطاء وإصلاحها

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

لا شيء يُترجَم — تبقى كل العبارات بلغتها المصدر

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

  1. CORS. أول طلب يرسله SDK هو authorize-project؛ فإذا لم تُدرج واجهة API الخاصة بك أصل التطبيق ضمن القائمة المسموح بها، يحظره المتصفح وتتوقف التهيئة عند هذه النقطة. تذكّر أن الأصل (origin) هو المخطط + المضيف + المنفذ بالضبط، فـ localhost:5173 وlocalhost:5174 أصلان مختلفان، وتتغير منافذ خوادم التطوير عندما يكون المنفذ المعتاد مشغولًا. أضف كل منفذ تطوّر عليه فعليًا إلى القائمة المسموح بها.
  2. بيانات اعتماد خاطئة. فقدان معرّف المشروع أو مفتاح API أو كتابته بشكل خاطئ يُفشل استدعاء التفويض نفسه. تعرض وحدة التحكم الطلب الفاشل وعنوان URL.
  3. أنت تشاهد اللغة الأساسية. في اللغة الأساسية تكون «الترجمة» هي النص المصدر نفسه — فلا يتغير شيء بصورة ظاهرة. بدّل إلى لغة مستهدفة لإجراء الاختبار.
فشل CORS والحل
# The SDK's first call is an authorize-project request.
# If the browser blocks it, NOTHING translates. Check the console for:
Access to fetch at 'https://your-api/api/authorize-project/...'
from origin 'http://localhost:5173' has been blocked by CORS policy

# Fix: allowlist the app's EXACT origin (scheme + host + port) on the API.
CORS_ALLOWED_ORIGINS=http://localhost:5173,https://app.example.com

عبارة واحدة لا تُترجم (بينما تُترجم الأخرى)

العبارة في شيفرتك هي مفتاح البحث — العبارة هي المفتاح. إذا ظهرت عبارة واحدة بنصها المصدر بينما تُترجم العبارات المجاورة لها، فهذا المفتاح غير موجود في فهرس المشروع:

لماذا لا تُحدث العبارات المفقودة خطأً؟

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

مفتاح الكتابة في التطوير، ومفتاح القراءة فقط في الإنتاج
# Development — write key: new phrases are discovered,
# registered, and machine-translated as you build.
VITE_LANGSYS_API_KEY=write-key

# Production — read-only key: fetches the finished catalog only.
# Unregistered phrases silently render their source text.
VITE_LANGSYS_API_KEY=read-only-key

يظهر العنصر النائب كما هو حرفيًا — "Hi %name%" أو "Hi {name}"

يعمل ثم يتعطل بعد أن أبدّل اللغات ذهابًا وإيابًا

حدّث SDK. هذه أخطاء حقيقية جرى إصلاحها في هذا المجال: العودة إلى اللغة الأولية/لغة SSR كانت تُبقي الكتالوج السابق نشطًا (أُصلح في langsys-js-typescript الإصدار 0.2.2)، وكان مستهلكو Translate/Phrase في كتل المحتوى قد يعلقون إلى الأبد على كتالوج مُحمَّل من الخادم (أُصلح في 0.2.3). إذا ظهرت لك نصوص بلغة قديمة أو كتل لا يكتمل تحميلها أبدًا، فقارن إصدارك المثبّت بسجل التغييرات الخاص بـ SDK الأساسية قبل تصحيح الأخطاء في شيفرتك.

من جهة الخادم: تعرض الصفحة الخطأ 500 بدلًا من التراجع السلس

يؤدي عميل حزمة PHP SDK إلى رمي استثناء عند إنشائه دون بيانات اعتماد، ولذلك يفشل تطبيق Laravel (أو PHP العادي) الذي تكون قيمة LANGSYS_API_KEY فيه فارغة عند حل الحاوية، قبل تشغيل أي ترجمة. عيّن بيانات الاعتماد (أو اربط عميلًا بديلًا إذا كان على التطبيق أن يعمل بدونها، كما تفعل التطبيقات التجريبية). وبعد توفر بيانات الاعتماد، فإن أعطال واجهة API أثناء التشغيل تُعالَج بسلاسة: فإذا تعذّر الوصول إلى الواجهة أو رفضت الطلب، يُعرَض النص المصدر ويُبلَّغ عن الاستثناء، ولا تتعطل الصفحة أبدًا.

من جهة الخادم: يتعلّق الطلب الأول ثم يصبح كل شيء سريعًا

مهلة HTTP في PHP SDK هي 30 ثانية، وقد تقترب منها نسخة API تستيقظ من حالة الخمول عند الاستدعاء الأول تمامًا. وينتهي ذلك الطلب إما ببطء (فيُسخّن ذاكرة التخزين المؤقت للكتالوج — وكل ما يليه يُقدَّم من الذاكرة المؤقتة) أو بانتهاء المهلة وعرض النص المصدر. إذا كان أول تحميل لصفحتك بعد فترة هدوء بطيئًا، فهذا هو السبب؛ فهو ناتج عن تسخين API وليس عن مشكلة في تكاملك.

من جهة الخادم: عرضتُ الصفحة بمفتاح كتابة لكن العبارة لا تظهر في لوحة التحكم

تُوضَع العبارات المكتشفة في قائمة انتظار أثناء الطلب، ثم تُرسَل بعد إرسال الاستجابة — وهذا هو سلوك الوسيط القابل للإنهاء (terminable middleware) في Laravel. حدّث لوحة التحكم بعد لحظات من تحميل الصفحة، وليس أثناءه. في بيئات التشغيل الطويلة الأمد للعمّال (Octane وFrankenPHP وRoadRunner) تأكد من استخدام التكامل المرفق مع حزمة SDK، إذ إن خطّاف الإيقاف العادي في PHP لا يُنفَّذ أبدًا بين طلبات العامل.

العرض على الخادم: تتسرّب الترجمات من طلب إلى آخر

تحتفظ حزمة JS الأساسية بـكتالوج لغة واحدة فقط في كل مرة، فهي كائن وحيد (singleton) على مستوى الوحدة. وأي خادم Node يعرض لغات مختلفة لطلبات متزامنة ستتنازع الطلبات فيه على الحالة نفسها. اجلب الكتالوج لكل طلب وهيّئ العميل منه، وهو النمط المتبع في أدلة Next.js وNuxt وSvelteKit، أو شغّل لغة واحدة لكل عملية.

ما زالت المشكلة قائمة؟ افتح بلاغاً (issue) في مستودع الـ SDK الخاص بك — typescript أو react أو vue أو svelte أو php أو laravel — مع مخرجات وحدة التحكم (أو سجل الخادم) للطلب الفاشل. أو راسلنا على [email protected].

ابحث في المستندات ومركز التعلّم