Skip to content
تم إنشاء هذه الصفحة وترجمتها بمساعدة الذكاء الاصطناعي. إذا لاحظت أي أخطاء، لا تتردد في المساهمة في تحسينها. تعديل على GitHub

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

تغطي هذه الصفحة المشكلات الأكثر شيوعاً التي تواجهها عند تشغيل PRX-Email، مع أسبابها وحلولها.

انتهاء صلاحية رمز OAuth

الأعراض: تفشل العمليات برمز خطأ Provider ورسالة عن الرموز المنتهية الصلاحية.

الأسباب المحتملة:

  • انتهت صلاحية رمز وصول OAuth ولا يوجد مزوّد تحديث مُعيَّن
  • يحتوي متغير البيئة *_OAUTH_EXPIRES_AT على طابع زمني قديم
  • مزوّد التحديث يعيد أخطاء

الحلول:

  1. التحقق من طوابع انتهاء صلاحية الرمز:
bash
echo $PRX_EMAIL_IMAP_OAUTH_EXPIRES_AT
echo $PRX_EMAIL_SMTP_OAUTH_EXPIRES_AT
# These should be Unix timestamps in the future
  1. إعادة تحميل الرموز يدوياً من البيئة:
rust
// Set fresh tokens
std::env::set_var("PRX_EMAIL_IMAP_OAUTH_TOKEN", "new-token");
std::env::set_var("PRX_EMAIL_SMTP_OAUTH_TOKEN", "new-token");

// Reload
plugin.reload_auth_from_env("PRX_EMAIL");
  1. تنفيذ مزوّد تحديث لتجديد الرمز التلقائي:
rust
let plugin = EmailPlugin::new_with_config(repo, config)
    .with_refresh_provider(Box::new(my_refresh_provider));
  1. إعادة تشغيل سكريبت بدء Outlook للحصول على رموز جديدة:
bash
CLIENT_ID='...' TENANT='...' REDIRECT_URI='...' \
./scripts/outlook_oauth_bootstrap.sh

TIP

يحاول PRX-Email تحديث الرموز قبل 60 ثانية من انتهاء صلاحيتها. إذا انتهت صلاحية رموزك أسرع من فترة المزامنة، تأكد من اتصال مزوّد التحديث.

فشل مزامنة IMAP

الأعراض: تعيد sync() خطأ Network، أو يُبلَّغ عن فشل في منشئ المزامنة.

الأسباب المحتملة:

  • اسم مضيف أو منفذ خادم IMAP غير صحيح
  • مشكلات في اتصال الشبكة
  • فشل المصادقة (كلمة مرور خاطئة أو رمز OAuth منتهي الصلاحية)
  • تحديد معدل خادم IMAP

الحلول:

  1. التحقق من الاتصال بخادم IMAP:
bash
openssl s_client -connect imap.example.com:993 -quiet
  1. فحص إعداد النقل:
rust
// Ensure host and port are correct
println!("IMAP host: {}", config.imap.host);
println!("IMAP port: {}", config.imap.port);
  1. التحقق من وضع المصادقة:
rust
// Must have exactly one set
assert!(config.imap.auth.password.is_some() ^ config.imap.auth.oauth_token.is_some());
  1. فحص حالة تراجع منشئ المزامنة. بعد فشل متكرر، يطبق الجدول الزمني تراجعاً أسياً. إعادة الضبط مؤقتاً باستخدام now_ts في المستقبل البعيد:
rust
let report = plugin.run_sync_runner(&jobs, now + 86400, &config);
  1. فحص السجلات المنظمة للحصول على معلومات تفصيلية عن الخطأ:
bash
# Look for sync-related structured logs
grep "prx_email.*sync" /path/to/logs

فشل إرسال SMTP

الأعراض: تعيد send() ApiResponse مع ok: false وخطأ Network أو Provider.

الأسباب المحتملة:

  • اسم مضيف أو منفذ خادم SMTP غير صحيح
  • فشل المصادقة
  • رفض المزوّد لعنوان المستلم
  • تجاوز حصة الإرسال أو تحديد المعدل

الحلول:

  1. فحص حالة صندوق الصادر:
rust
let outbox = plugin.get_outbox(outbox_id)?;
if let Some(msg) = outbox {
    println!("Status: {}", msg.status);
    println!("Retries: {}", msg.retries);
    println!("Last error: {:?}", msg.last_error);
    println!("Next attempt: {}", msg.next_attempt_at);
}
  1. التحقق من إعداد SMTP:
rust
// Check auth mode
println!("Auth: password={}, oauth={}",
    config.smtp.auth.password.is_some(),
    config.smtp.auth.oauth_token.is_some());
  1. التحقق من أخطاء التحقق. ترفض واجهة الإرسال:

    • to أو subject أو body_text فارغة
    • علامة ميزة email_send معطّلة
    • عناوين بريد إلكتروني غير صالحة
  2. الاختبار مع فشل محاكي للتحقق من معالجة أخطائك:

rust
use prx_email::plugin::SendFailureMode;

let response = plugin.send(SendEmailRequest {
    // ... fields ...
    failure_mode: Some(SendFailureMode::Network), // Simulate failure
});

صندوق الصادر عالق في حالة "sending"

الأعراض: سجلات صندوق الصادر لها status = 'sending' لكن العملية تعطلت قبل الإنهاء.

السبب: تعطلت العملية بعد المطالبة بسجل صندوق الصادر لكن قبل إنهائه كـ sent أو failed.

الحل: استرداد السجلات العالقة يدوياً عبر SQL:

sql
-- Identify stuck rows (threshold: 15 minutes)
SELECT id, account_id, updated_at
FROM outbox
WHERE status = 'sending' AND updated_at < strftime('%s','now') - 900;

-- Recover to failed and schedule retry
UPDATE outbox
SET status = 'failed',
    last_error = 'recovered_from_stuck_sending',
    next_attempt_at = strftime('%s','now') + 30,
    updated_at = strftime('%s','now')
WHERE status = 'sending' AND updated_at < strftime('%s','now') - 900;

مرفق مرفوض

الأعراض: يفشل الإرسال بـ "attachment exceeds size limit" أو "attachment content type is not allowed".

الحلول:

  1. فحص سياسة المرفق:
rust
let policy = &config.attachment_policy;
println!("Max size: {} bytes", policy.max_size_bytes);
println!("Allowed types: {:?}", policy.allowed_content_types);
  1. التحقق من حجم الملف ضمن الحد (الافتراضي: 25 ميغابايت).

  2. إضافة نوع MIME إلى القائمة المسموح بها إذا كان آمناً:

rust
policy.allowed_content_types.insert("application/vnd.ms-excel".to_string());
  1. للمرفقات القائمة على المسار، تأكد من أن مسار الملف تحت جذر تخزين المرفقات المُعيَّن. المسارات التي تحتوي على ../ أو الروابط الرمزية التي تُحلّ خارج الجذر مرفوضة.

خطأ ميزة معطّلة

الأعراض: تعيد العمليات رمز خطأ FeatureDisabled.

السبب: علامة الميزة للعملية المطلوبة غير مفعّلة للحساب.

الحل:

rust
// Check current state
let enabled = plugin.is_feature_enabled(account_id, "email_send")?;
println!("email_send enabled: {}", enabled);

// Enable the feature
plugin.set_account_feature(account_id, "email_send", true, now)?;

// Or set the global default
plugin.set_feature_default("email_send", true, now)?;

أخطاء قاعدة بيانات SQLite

الأعراض: تفشل العمليات برمز خطأ Storage.

الأسباب المحتملة:

  • ملف قاعدة البيانات مقفل بعملية أخرى
  • القرص ممتلئ
  • ملف قاعدة البيانات تالف
  • لم تُشغَّل الترحيلات

الحلول:

  1. تشغيل الترحيلات:
rust
let store = EmailStore::open("./email.db")?;
store.migrate()?;
  1. التحقق من قاعدة البيانات المقفلة. يمكن أن يكون اتصال كتابة واحد فقط نشطاً في كل مرة. زد مهلة الانشغال:
rust
let config = StoreConfig {
    busy_timeout_ms: 30_000, // 30 seconds
    ..StoreConfig::default()
};
  1. التحقق من مساحة القرص:
bash
df -h .
  1. الإصلاح أو إعادة الإنشاء إذا كانت قاعدة البيانات تالفة:
bash
# Back up the existing database
cp email.db email.db.bak

# Check integrity
sqlite3 email.db "PRAGMA integrity_check;"

# If corrupt, export and reimport
sqlite3 email.db ".dump" | sqlite3 email_new.db

مشكلات مكوّن WASM

خطأ حارس الشبكة

الأعراض: تعيد عمليات البريد الإلكتروني المستضافة بـ WASM خطأ EMAIL_NETWORK_GUARD.

السبب: مفتاح أمان الشبكة غير مفعّل.

الحل:

bash
export PRX_EMAIL_ENABLE_REAL_NETWORK=1

قدرة المضيف غير متاحة

الأعراض: تعيد العمليات EMAIL_HOST_CAPABILITY_UNAVAILABLE.

السبب: وقت التشغيل المضيف لا يوفر قدرة البريد الإلكتروني. يحدث هذا عند التشغيل خارج سياق WASM.

الحل: تأكد من إعداد وقت تشغيل PRX لتوفير استدعاءات مضيف البريد الإلكتروني للمكوّن.

منشئ المزامنة يتخطى المهام باستمرار

الأعراض: يُبلَّغ عن attempted: 0 من منشئ المزامنة رغم إعداد المهام.

السبب: جميع المهام في حالة تراجع بسبب فشل سابق.

الحلول:

  1. فحص حالة تراجع الفشل بفحص السجلات المنظمة.

  2. التحقق من إمكانية الوصول إلى الشبكة ومصادقة IMAP قبل إعادة التشغيل.

  3. إعادة ضبط التراجع باستخدام طابع زمني في المستقبل البعيد:

rust
let report = plugin.run_sync_runner(&jobs, now + 86400, &default_config);

معدل فشل إرسال مرتفع

الأعراض: تُظهر المقاييس عدداً مرتفعاً من send_failures.

الحلول:

  1. فحص السجلات المنظمة مرشحة بـ run_id وerror_code:
bash
grep "prx_email.*send_failed" /path/to/logs
  1. التحقق من وضع مصادقة SMTP. تأكد من ضبط واحد بالضبط من كلمة المرور أو oauth_token.

  2. التحقق من توفر المزوّد قبل تفعيل النشر الواسع.

  3. فحص المقاييس:

rust
let metrics = plugin.metrics_snapshot();
println!("Send failures: {}", metrics.send_failures);
println!("Retry count: {}", metrics.retry_count);

الحصول على المساعدة

إذا لم يحل أي من الحلول أعلاه مشكلتك:

  1. تحقق من المشكلات الموجودة: github.com/openprx/prx_email/issues
  2. قدّم مشكلة جديدة مع:
    • إصدار PRX-Email (تحقق من Cargo.toml)
    • إصدار سلسلة أدوات Rust (rustc --version)
    • مخرجات السجل المنظم ذات الصلة
    • خطوات إعادة الإنتاج

الخطوات التالية

Released under the Apache-2.0 License.