Hata işleme ve mesaj normalizasyonu

PayCal’in tüm frontend modüllerinde hata raporlamasını, kullanıcıların hassas ayrıntılar görmeden anlamlı, güvenli ve tutarlı hata geri bildirimi alması için nasıl standartlaştırdığı.

Genel bakış ve amaç

Kullanıcılar hatayla karşılaştığında ne olduğunu ve nasıl düzeltileceğini açıklayan net geri bildirim almalıdır. Ham backend hata mesajları şu amaçlarla normalize edilir:

  • Gürültüyü kaldırmak: gereksiz "Error:" öneklerini ve boşlukları temizlemek
  • Sızıntıyı önlemek: hassas implementasyon ayrıntılarının kullanıcıya ulaşmamasını sağlamak
  • Fallback sağlamak: boş veya bozuk hatalarda güvenli mesaj göstermek
  • Tutarlılık sağlamak: aynı mantığı tüm 11+ frontend modülünde uygulamak
  • Debugging’i iyileştirmek: tam ayrıntıları Phantom Wing’e loglayıp kullanıcılara güvenli özetler göstermek

Sorun: genel hatalar ve anlamlı hatalar

Standartlaştırmadan önce PayCal modülleri ad-hoc hata işleme kullanıyordu:

// ❌ BAD: Exposes raw error, duplicates logic
PC.showToast(error?.message || 'Import failed.');
PW.error(`Import failed: ${error.message}`);

Bu yaklaşımın sorunları:

  • Kullanıcılar "ECONNREFUSED: Connection refused" gibi kafa karıştırıcı ham mesajlar görür
  • Her modül kendi fallback mantığını ayrı uygular
  • Boşluk temizleme veya önek kaldırma tutarlı değildir
  • Boş hata mesajları UI’da "undefined" olarak görünebilir

Çözüm: standartlaştırılmış hata resolver’ı

Tüm PayCal frontend modülleri artık hata mesajlarını normalize eden birleşik bir resolver fonksiyonu kullanır:

// ✅ GOOD: Normalized, consistent, safe
const resolveThrownMessage = (error, fallbackMessage) => {
  const raw = typeof error?.message === 'string' 
    ? error.message 
    : String(error || '');
  const normalized = raw.replace(/^Error:\s*/i, '').trim();
  return normalized !== '' ? normalized : fallbackMessage;
};

Kullanım:

// In catch blocks across modules
try {
  await updateProfile(data);
} catch (error) {
  const message = resolveThrownMessage(error, 'Unable to update profile.');
  PC.showToast(message, 'error');  // User sees meaningful feedback
  PW.error(message);                // Logged for debugging
}

Uygulama kapsamı

Nisan 2026 itibarıyla bu standart hata işleme deseni 11 frontend modülünde yaklaşık 40+ normalize catch bloğuna uygulanmıştır:

Kimlik doğrulama ve ayarlar (7 modül)

  • html/js/auth-recovery/index.php (4 catches)
  • html/js/signin/index.php (2 catches)
  • html/js/signin/verification-reminder.js (2 catches)
  • html/js/signin/verification-status-banner.js (1 catch)
  • html/js/settings/index.php (8+ catches)

Core ve veri modülleri (4 modül)

  • html/js/core/network.js (3 catches)
  • html/js/core/index.php (5 catches)
  • html/js/core/billing.js (5 catches)
  • html/js/earnings/index.php (4 catches)

Yüksek değerli modüller (10+ catch noktası):

  • html/js/organizations/index.php - Org management, access requests, audit trails (19+ catches)
  • html/js/sites/index.php - Site CRUD, earnings, orphan work recovery (10+ catches)
  • html/js/calendar/calendar.js - Day-entry operations, copy/paste/delete (2 catches)

Hata kategorileri ve işleme desenleri

Resolver birkaç hata kategorisinde tutarlı uygulanır:

1. Ağ isteği hataları

// Network module: HTTP errors, timeouts, connection issues
async function deleteResource(ep, id) {
  try {
    // ...fetch logic...
  } catch (error) {
    const resolved = resolveThrownMessage(error, 'Network error');
    const msg = `[deleteResource] ${resolved}`;
    PW.error(msg);
    throw new Error(msg);
  }
}

2. API yanıt işleme

// Billing/Settings: Server returned error message in payload
try {
  const response = await fetch('/api/v1/billing/subscription');
  const payload = await response.json();
  if (!response.ok) {
    throw new Error(payload?.message || 'Unable to load billing status.');
  }
} catch (error) {
  const resolved = resolveThrownMessage(error, 'Unable to load billing status.');
  setScreenReaderStatus(resolved);
}

3. UI işlem hataları

// Calendar/Organizations: User-initiated actions (paste, delete, update)
button.addEventListener('click', async () => {
  try {
    await performAction();
    PC.showToast('Success!', 'save');
  } catch (error) {
    const message = resolveThrownMessage(error, 'Action failed. Try again.');
    PC.showToast(message, 'error');
  }
});

4. Asenkron başlatma

// Core modules: Startup or dependent initialization failures
try {
  NavigationToggle.init();
} catch (err) {
  const resolved = resolveThrownMessage(err, 'Navigation init failed');
  PW.warn(resolved);  // Logged but doesn't block page
}

Güvenlik değerlendirmeleri

Hata mesajı normalizasyonu kullanıcı gizliliğini ve sistem bütünlüğünü korur:

  • Veritabanı ayrıntısı yok: "UNIQUE constraint failed on email" gibi backend hataları API sınırında yakalanır
  • Dosya yolu yok: dosya yolu veya süreç ayrıntısı veren sistem hataları temizlenir
  • Auth sızıntısı yok: kimlik doğrulama hataları bir hesabın var olup olmadığını asla göstermez
  • CORS/ağ ayrıntısı yok: transport hataları generic connection mesajlarına normalize edilir
  • Güvenli fallback: tüm catcher’larda açık fallback vardır; "undefined" veya "null" gösterilmez

Kullanıcı deneyimi faydaları

Bu standartlaştırma kullanıcıya daha net, güvenli ve tutarlı geri bildirim verir; destek ve debugging’i kolaylaştırır.

  • Mesajlar implementasyon ayrıntısı göstermeden anlaşılırdır
  • Backend hatası eksik veya bozuk olsa da fallback metni güvenli kalır
  • Logging, hassas değerleri UI’a sızdırmadan debugging için yararlı kalır

Debugging ve destek akışı

Destek ekibi tutarlı resolver yoluna güvenebilir ve gerektiğinde tam teknik ayrıntı için Phantom Wing loglarını inceleyebilir.

  • Kullanıcı normalize edilmiş mesaj görür
  • Phantom Wing tam hata bağlamını özel olarak kaydeder
  • Destek, ham backend yanıtını göstermeden sorun sınıfını ilişkilendirebilir

Test ve kalite güvencesi

Normalizasyon mantığı odaklı modül testleri ve ana frontend akışlarındaki entegrasyon kontrolleriyle kapsanır.

Bakım ve gelecekteki genişletmeler

PayCal daha fazla modül ekledikçe, özel hata formatlama kopyalamak yerine aynı resolver deseni tekrar kullanılmalıdır.

  • Yeni modüller shared resolver’ı doğrudan çağırmalıdır
  • Modüle özel fallback mesajları kısa ve kullanıcı odaklı kalmalıdır
  • Resolver değişiklikleri temsilci akışlarda regression test edilmelidir

Bu, codebase büyüdükçe davranışı öngörülebilir tutar ve ikinci bir modüle özel hata işleme kuşağını önler.

Özet: PayCal hata işleme standardı

PayCal frontend hata işlemeyi standartlaştırdı; kullanıcılar güvenli ve tutarlı mesajlar alırken geliştiriciler debugging için gereken bilgiyi korur.

  • Gösterimden önce hata mesajlarını normalize edin
  • Implementasyon ayrıntılarını kullanıcılardan gizleyin
  • Boş veya bozuk hatalar için açık fallback metni kullanın
  • Destek ve debugging için teknik ayrıntıyı özel olarak loglayın