Tümünü yakala veya temel istisna sınıfında istisnaları günlüğe kaydetmek daha mantıklı mı?


15

Oldukça büyük bir web uygulamasını yeniden düzenleme sürecindeyim. En büyük sorunlardan biri tutarsız hata işleme ve ben mantıklı bir strateji bulmaya çalışıyorum. Ben aracılığıyla, özel bir hata işleyicisi oluşturduk set_error_handler esasen PHP hataları döndüğünü ErrorExceptions ve özel bir baz istisna sınıftan doğrudan devralır o özel durum .

Üretimde, set_exception_handler aracılığıyla genel bir istisna catch-all kullanıyorum ve karışıma istisna günlüğü * eklemek üzereyim . Benim açmazım, temel istisna sınıfında veya tümünü yakalamada gerçek günlüğe kaydetmenin nerede yapılacağı.

Hepsini yakalamak için birkaç neden düşündüm:

  • Kodda, temel istisna sınıfının uygun bir alt öğesine dönüştürülmesi gereken birkaç istisna vardır. Bu gerçekleşene kadar, tüm istisnalar kaydedilmez.
  • Her nasılsa onu yakalamada yapmak daha doğal geliyor, bir temel istisna sınıfı sadece bundan daha fazlasını yapmamalıdır. (Tek bir sorumluluk ilkesi olabilir, ama sadece yanlış yönlendirilmiş bir his olabilir)

ve temel istisna sınıfına giriş yapmanın bir nedeni:

  • Şu anda her şeyi yakalama sadece üretimde kullanılmaktadır. Diğer ortamlarımızda (geliştirme, test etme) tanıtmak kolay olurdu, ancak üretimde 404/503 hata sayfalarına çevrildiklerinden, hatalar ortam başına farklı şekilde ele alındığından, birkaç ayar gerektirecektir.

İstisnaların nereye kaydedileceğine dair kabul edilebilir bir uygulama var mı?

* Günlüğe kaydetme ilk önce bir metin dosyasına yazmayı içerir ve belirli istisna türleri için posta göndermeye gelişebilir.


@ Unholysampler'ın cevabı tarafından yapılan bazı açıklamalar :

2 * 10 ^ 6 sloc kod temeli, ben üzerinde hiçbir kontrol var üçüncü parti şeyler bir sürü karşı karşıya ve bazı kod PHP ön tarihler istisnalar üzerinde kontrol var. Ve ayrıca son derece berbat bir kod var, neredeyse düşünmeyi bırakmak zorunda kaldığımız ve sadece hacklendiğimiz uzun bir yoğun baskı döneminden kurtuluyoruz.

Tüm tutarsızlıkları ele almak ve mantıklı bir hata işleme yaklaşımı sunmak için aktif olarak yeniden düzenleme yapıyoruz, ancak bu biraz zaman alacak. Hataların uygun şekilde ele alındığı noktaya gelene kadar ne yapacağımla daha fazla ilgileniyorum. Muhtemelen bir noktada mantıklı bir istisna stratejisi hakkında başka bir soru soracağım.

Günlüğe kaydetmenin arkasındaki ana motivasyon, üretimde kötü bir şey olduğunda telefonuma bir e-posta almaktır. Veri dökümlerinin çok büyük hale gelmesi umrumda değil, eğer yaparlarsa eskilerini silecek bir cron işim olacak.

Yanıtlar:


11

Kısacası, bir istisnanın varlığını günlüğe kaydetmeniz gereken tek zaman, onu işlediğiniz zamandır.

Bir istisna attığınızda, bunun nedeni kodunuzun doğru şekilde ilerleyemediği bir duruma ulaşmış olmasıdır. Bir istisna atarak, programınıza meydana gelen hata hakkında belirli bir mesajı temsil edersiniz. Düzgün bir şekilde işlenebilecek bir noktaya gelene kadar bir istisna yakalamamalısınız.

Ana uygulamanızın bir parçası olarak yazdığınız kod, atılabilecek özel durumlar ve ne zaman atılabileceğinin farkında olmalıdır. Bir istisna dışında üretken bir şey yapamıyorsanız, onu yakalamayın. İşlenene kadar bir istisna günlüğe kaydetmeyin. Program yönetimi bağlamında istisnanın ne anlama geldiğini ve buna nasıl yanıt verileceğini yalnızca işleme kodu bilir. Buraya bir günlük mesajı yazmak mantıklı olabilir. Bir günlük kaydı çerçevesi kullanıyorsanız, ileti için bir günlük düzeyi ayarlayabilir ve potansiyel olarak filtreleyebilirsiniz. Bu, oluşabilecek ancak kritik olmayan ve temiz bir şekilde kurtarılabilen istisnalar için iyi çalışır.

İstisna yakalamanız, kodunuzun çirkin bir ölüme çarpmasını önlemek için son hendek çabanızdır. Bu kadar ilerlediyseniz, yapabileceğiniz tüm durum ve hata bilgilerini kaydedersiniz. Sonra kullanıcıya her şeyin durmadan önce programın çöktüğünü söylemek için elinizden geleni yaparsınız. Amacınız asla bu kodu çalıştırmamak olmalıdır.

Günlüğe kaydetmeyi temel sınıfa gömmek yukarıdaki yönergeleri izlemez. Temel sınıf, kodun durumu hakkında hiçbir şey bilmiyor. (Ayrıştırmaya dayalı kararlar veren kod yazamayacağınız için yığın izlemesi sayılmaz.) Temel sınıf, önem derecesini veya kural dışı durumun nasıl ele alınabileceğini belirtmek için hiçbir şey yapamaz. Her zaman büyük veri dökümleri ve yığın izleri istemezsiniz.


Cevabınız tarafından sorulan soruya bazı açıklamalar ekledim. Topladığım şeyden, sorunun pratik tarafında, hepsini yakalamayı öneriyorsunuz?
yannis

1
@YannisRizos: Evet, catch-all'ı ilk adımınız olarak uygulamalısınız. Yakalama-tüm hakkında söylediğim, kod akışınızın normal bir parçası olarak kullanmadığınızdan emin olmak için daha fazla oldu. İşlenmeyen bir özel durum işleyici uygulamak önemlidir, çünkü kodunuz her kötü bir şey yaptığında çok fazla bilgi almanızı sağlar.
unholysampler

"Yerine geçmedikçe günlüğe kaydedilmesi gereken bir sürü şey var" kavramını rahatlıkla işleyebilecek hiçbir kayıt çerçevesi yok mu? Bir istisna gören her katman, önceki günlük raporunun gevşemesi sırasında yeni bir istisna atılırsa, son günlük raporunun yerine geçmez ve böylece kaydedilmesi dışında, bir öncekinin yerine geçebilir. Hiçbir çerçeve böyle bir modeli desteklemiyor mu?
supercat

3

Diliniz / çalışma süreniz istisnanın kaynağını kolayca belirlemenize izin vermezse, atma sırasında günlüğe kaydetmenin bir durumu vardır. C ++ ve bazı JS motorları, yakaladığınız zaman istisnadaki dosya + satırını veya çağrı yığınını göstermez / ancak bu bilgiler istisnayı oluşturduğunuz sırada kullanılabilir.

Çözümümüz, bu sorunları teşhis etmeye çalışırken istisna türünün ucuz bir yığınla birlikte günlüğe kaydedilmesini sağlamak için çalışma zamanı yapılandırmasını kullanan bir mekanizma sağlamaktı.


+1 Bu kesinlikle atışta oturum açmak için iyi bir durum ... PHP de yakalamada tam bir yığın izlemesi sağlıyor, bu yüzden muhtemelen başka yöne gideceğim ...
yannis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.