Neden tüm ifadeleri Try-Catch'a yazmalıyım?


12

Şirket başkanım Try-catch deyimleri içinde hepsini yazmam gerektiğini söylüyor. Şimdi, burada 'özür dilemekten daha iyi güvende ol' yaklaşımını anlayabiliyorum, ancak Etiketler oluşturulduğunda, formun konumu belirlendiğinde bir istisna olacağını düşünmek çok fazla yürekli değil. böyle basit operasyonlarda İstisnalar olduğu durumlar olmuştur.


4
Bu , daha iyi performans için tüm SQL'in saklı yordamlar olarak yazılması gerektiğini söyleyen aynı kişiler tarafından vızıltı terimleri gibi görünüyor .
00'de sünger

5
"Kodunuz bir çalışma zamanı hatası oluşturuyorsa, işten çıkarıldınız." Rakibinizin direksiyon simidini attığını ve fren pedalını camdan çıkardığını görene kadar tavuk oyunu eğlencelidir.
JeffO

4
@Jeff O - Aslında yazılım geliştirmede rakibin bir yük treni olduğuna inanıyorum.
Joris Timmermans

5
Bu istisna işleme tarzı için duyduğum en iyi ifade "Cesedi dik pozisyonda çivilemek", yani uygulamayı beklenmedik bir durumda bırakıyor. Fail Fast, Fail Loudly çok daha modern bir yaklaşımdır, böylece tüm hataları çözebilirsiniz.
Brook

2
Talebin konusu ilgisiz ... sadece "şirket başkanım kod yazmam gerektiğini söylüyor ..." demek büyük bir kırmızı bayrak. Mikro yönetim ... bu onun işi değil.
JoelFan

Yanıtlar:


14

Şirket başkanım Try-catch deyimleri içinde hepsini yazmam gerektiğini söylüyor.

Eh, bu biraz abartılı ve sadece gürültülü koda yol açar. Bir try catch işleyici ile yazılmış tüm kodların (örneğin her yöntem) olmasının faydaları nelerdir? Sadece çoğu durumda düzeltilecek bir hata olduğunu söyler. Çoğu zaman, istisna ilk etapta önlenebilir ve kaçınılmalıdır.

Yığın izine bir bakış, hata yöntemi yakalamanın kendisini gerçekleştirmese bile, kodunuzdaki nedeni ortaya çıkarmak için yeterlidir. Geliştiricilerin istisnalarda yığın izlerini bozduğu zamanlar vardır, ancak çok sayıda istisna işleyiciniz olduğunda bu çok daha sık görülür. Her şey gibi: Biraz iyi, ama çok fazla zehir.

İstisna yönetimi gerçekten oldukça basittir:

Özel Durumları Yakala

  • İstisnaya tepki olarak özel bir eyleme ihtiyacınız olduğunda
  • bir istisna, ele alınmazsa programı tutarsız bir durumda bıraktığında

Bunu düşünürseniz, ortaya çıkan bir istisnayı ele almak için iyi olan her zaman sadece bir yer vardır. Ve böylece işleyici bu yerde olmalı.

Birçok istisna ilk etapta bile atılmamalıdır, bu nedenle kontrol yapılarınızı istisna işleme etrafında kurmayın, mümkün olan her yerde ve mümkün olan durumlarda istisnaların oluşmasından kaçınmaya çalışın.

İşler (tamir edilemez şekilde) yanlış gittiğinde erken çökmeyi unutmayın. Tüm kodu try-catch deyimlerine koymak saçmadır, ancak TÜM istisnaları bildirmeyi ve kaydetmeyi unutmayın.


+1 Bunu sadece gürültülü koda değil, daha da kötü performansa götürür. Bir try bloğuna ifadeler koyduğunuzda, HotSpot Derleyici başka türlü yapacağı optimizasyonları uygulayamaz.
Oliver Weiler

@Oliver Weiler: HotSpot derleyicisinin try / catch bloklarında hangi optimizasyonları yapmadığını açıklayan bir alıntı var mı?
Kaypro II

16

ancak Etiketler oluşturulduğunda bir istisna olacağını, formun pozisyonunun ayarlandığını düşünmek çok içten değil mi? böyle basit operasyonlarda İstisnalar olduğu durumlar olmuştur.

Kesinlikle evet! Öngörmediğin şeylerin yanlış gitmesi için her zaman bir yol vardır. Ve "tavuk kalpli" bu bağlamda kullanmak için saçma bir ifadedir; yazılım geliştirme potansiyel sorunları göz ardı ederek makinenizi kanıtlamakla ilgili değildir.

Ne olduğunu geçerli bir soru bu kadar olup olmadığıdır yararlı istisnalar kodlama standartları onlar gerektiğini söylüyorlar noktada yakalanabilmesi için. İfadeniz, her yöntem gövdesinin etrafında deneme / yakalama bloğuna sahip olmanız gerektiği gibi okunur ve bu genellikle saçmadır, çünkü genellikle bir istisna ile hemen faydalı bir şey yapamazsınız ve bu aslında istisnaların bütün mesele: onlara izin vermeyi seçebilirsiniz ele alınacak çağrı yığınını uygun noktaya yaymak.


13
Uygulamalarım istisnalar atmaktan daha iyi biliyor, yoksa hayatlarının yenilmesini sağlayacaklar. Tavuk kalpli olduğunuzu düşündüklerinde, her tarafınıza çarparlar.
JeffO

@Michael Borgwardt: hehe, bu yüzden beni indirdin. Bu soruya önem vermediniz ve tek aşağılık görevimde. Nefsinizle veya benlik saygınızla ciddi bir probleminiz var gibi görünüyor. Bunu diğer tekliflerde de fark ettim. Diğer programcıların da iyi cevapları var.
Falcon

@Falcon: Bu soruya hiçbir şey indirmedim. Sizi aksini düşünmeye iten hiçbir fikrim yok, ama eğer birisi ciddi bir ego problemi varsa, o sensin.
Michael Borgwardt

@Michael Borwardt: Belki de yanılıyorum. Bu durumda özür dilerim. Bu sadece sizin kendi sorunuzun aşağı oyu olabilir. Üzgünüm.
Falcon

8

Bunu tersine çevirirdim. Evet, genel bir kural istisnası işleme iyi bir şeydir, ancak yakalanacağı noktada gerçekten olası tüm istisnaları mantıklı bir şekilde ele alabilir misiniz? Bazen, kritik yazılım yazmıyoruz, özellikle o olduğunu basitçe çökmesine şeylerin çok yanlış gittiğinde bazı yarı yolda kontrollü bir şekilde yakmak daha iyidir.

Eğer yakalanabilecek her bir istisnayı kaldırabileceğinizden% 100 emin olamıyorsanız, muhtemelen bir çeşit genel istisna işleyicisi yazmaktan, programın ana döngüsünü içine sarmaktan daha iyidir - bunu açıkça nasıl yapacağınızın tam mekaniği Hangi dilde çalıştığınıza bağlıdır. Orada, istisna hakkında olabildiğince fazla ayrıntı günlüğe kaydet, program durumunu kaydet ( kullanıcının şu anda çalıştığı veri deposundan başka bir yerde) - unutmayın, bu noktada hepsi bozuk olabilir ), ve bunun gibi. Ardından, istisnayı yeniden düşünün ve işletim sisteminin uygun görmesine rağmen işlemesine izin verin. Bu tümünü yakalama özel durum işleyicisinde, yıkıcı başarısızlığa hazırlıklı olun. Daha sonra, program yeniden başlatıldığında, bu durumun herhangi bir şekilde yararlı olup olmadığına bakın ve varsa kurtarılabilecekleri geri yükleyin; ve muhtemelen kullanıcıya bir hata raporu göndermesini öneriyoruz.


5
+1: Hemen doğru şekilde başa çıkamıyorsanız asla bir istisna yakalamayın. (Ne yazık ki, bazen sadece tekrar serbestçe dolaşmak için izin vermelisiniz, ancak API zorlamasının bir parçası olarak farklı bir tür olarak etiketlendi: Bundan nefret ediyorum.)
Donal Fellows

6

Genel olarak, catch / catch kullanımı çok fazla kullanımdan kaldırılmıştır, çünkü catch bloğu kaynaklar açısından çok pahalıdır. Kullanmayı dene / yakala bana risk yönetimini hatırlatıyor . Risk yönetiminin iki boyutu vardır:

  1. Risk olasılığı
  2. Sahip olabileceği hasar

Şimdi, evinizden dışarı çıkarsanız, bir yerlerde başınızın üzerine düşen bir piyano olması muhtemel değildir (belki% 0.001), ancak sizi öldürebilir.

İstisna yönetimi böyle. Deneyin blok pahalı değil. Ancak catch bloğu gerçekten pahalıdır, çünkü yığın izlemesi tablosu oluşturmak ve başka şeyler yapmak gerekir. Bu nedenle try / catch blokları hakkında bir karar verirken, muhtemelen catch bloğuna kaç kez vurduğunuzu düşünmelisiniz. 10.000 kullanıcı arasında sadece 1 kez vurursanız kullanın. Ancak bu bir formsa ve kullanıcı muhtemelen% 50 kez doğru doldurmuyorsa, o zaman bir try / catch bloğunu harekete geçirmekten kaçınmalısınız.

İstisna oluşma olasılığının yüksek olduğu yerlerde, istisna oluşumunu if {} else {}önlemek için blokların kullanılması önerilir . Örneğin, yazmak yerine iki sayıyı bölmek istediğiniz yer:

try
{
    int result = a/b;
}
catch (DivisionByZeroException ex)
{
    // Showing a message here, and logging of course.
}

yazmalısın:

if (b == 0)
{
    int result = a/b;
}
else
{
    // Showing a message to user to change the value of b, etc.
}

2
Temelde sadece uygulama mantığı olan "istisnalar" ile ilgilenmek için if / else komutunu kullanmak üzere +1.
Morgan Herlocker

Kullanıcı ile ilgili ise, bilgisayarların insanlardan çok daha hızlı olduğunu unutmayın. Form gönderimlerinin% 50'sinde atılan bir istisna, birçok kullanıcıyla bile saniyede sadece birkaç kez gerçekleşebilir.
Donal Fellows

1
Deneme / yakalama bloklarından kaçınma konusunda size katılmıyorum. İstisnaları sürekli olarak tahmin etmeye çalışmak hataya yatkındır, geliştirici zamanında pahalıdır ve kodunuzu okumayı zorlaştırır. Bir milyon istisna fırlatan ve onları yakalayan bir döngü , makinemde çalıştırmak için 500ms (boş bir döngü için 1ms), bu da vakaların% 99.99'unda (ve tüm UI kodlarında) gerçek dünyadaki performans farkı değildir. Performans cezasının önemli olduğunu bildiğiniz durumlar dışında istisnalar kullanmalısınız, çünkü kodunuzu daha güvenilir hale getirirler ve önceki kodun başarıyla yürütüldüğünü varsaymanızı sağlarlar.
Kaypro II

@ cosmic.osmo, yığın izlemesini alıyor musunuz veya sadece yakalıyor musunuz?

3

Uygun olduğunda try-catch kullanmalısınız, ancak lütfen oh lütfen tüm istisnaları yakalamayın ve hatta günlüğe kaydetmeyin. Bu noktada kod kokusu ve kalitesiz çalışma.


1
Günlük kaydı için +1. Vahşi doğada programlar kara kutulardır. Başarısız olduklarında, "İşte olanlar" yazan bir günlük sorunu çözmek için çok uzun bir yol kat ediyor. Programlarımda bildirilmeyen hatalar yaşadım ve yalnızca günlükte bulduktan sonra ortaya çıktılar.
Andrew Neely

2

Şahsen istisnalar dayanamıyorum, onlar ÇOK, ÇOK, ÇOK doğru idare etmek zor. Ve bozuk verileri bozmaya çalışmak ÇOK, ÇOK, ÇOK zor!

http://blogs.msdn.com/b/mgrier/archive/2004/02/18/75324.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

http://www.joelonsoftware.com/items/2003/10/13.html

Gibi her işlevi çağırmazsanız:

try
{
    TrivialFunction();
}
catch(TypeAException)
{
    //MaybeFix
}
catch(TypeBException)
{
    //MaybeFix
}
catch(TypeCException)
{
    //NO FIX - CORRUPT DATA
}
catch(TypeDException)
{
    //NO FIX - UNKNOWN STATE
}
catch(OutOfMemoryException)
{
    //Try to fix this one! Destructors might allocate on their own ;)
}
catch(Exception)
{
    //Nothing to see here, move on, everything is OK ;)
}

Her çıkış noktasında doğru şekilde temizlemenin bir yolu yoktur. İstisnalar ZOR!

İstisnalar hakkında tek iyi şey, onları yakalamazsanız, uygulamanın beklenmedik davranışlara çarpmasıdır.

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.