İstisna'yı kim okumalı?


27

İstisnaları tasarlarken, bir kullanıcının veya bir geliştiricinin anlaması gereken mesajlar yazmalı mıyım? İstisna mesajlarının okuyucusu kim olmalı?

İstisna mesajlarının hiç kullanışlı olmadığını görüyorum ve bunları yazmakta her zaman zorlanıyorum. Kurallara göre, istisnanın türü bize bir şeyin neden işe yaramadığını ve özel özelliklerin dosya adları, dizinler, anahtarlar vb. Gibi daha fazla bilgi ekleyebildiğini söylemeli. Otomatikleştirilmiş bir mesaj da yapabilir ve içerdiği her şey, bir ek özellik listesi içeren istisna adıdır. Bu tam olarak el yazısı bir metin kadar faydalı olacaktır.

Mesaj yazmamak daha iyi olmaz mıydı ama bunun yerine, farklı dillerde belki de anlamlı kodlar oluşturmayı önemseyen özel istisna oluşturuculara sahip olmak yerine, bunları kodda kodlamak yerine?


Bu sorulardan herhangi birinin soruma cevap verip vermediği soruldu:

İkisini de okudum ve cevaplarından memnun değildim. Genel olarak kullanıcılar hakkında konuşurlar ve muhatabın yerine mesajın içeriğine odaklanırlar ve sonuçta en az iki kişinin olabileceği ortaya çıkar: son kullanıcı ve geliştirici. İstisna mesajları yazarken hangisiyle konuşmam gerektiğini asla bilemiyorum.

Ünlü mesajın istisna türünün ismini sadece farklı kelimelerle tekrar ettiği için hiçbir gerçek değeri olmadığını düşünüyorum. Onları otomatik olarak mükemmel şekilde üretebiliyorum.

Bana göre istisna mesajı, okuyucularının farklılaşmasından yoksun. Bir mükemmel son kullanıcı için bir tane ve geliştirici için: biri istisna mesajının en az iki versiyonunu sunmak gerekir. Ona sadece bir mesaj vermek çok genel. Bir geliştirici mesajı daha sonra İngilizce olarak yazılmalıdır, ancak son kullanıcının mesajının başka dillere çevrilmesi gerekebilir. Bunların hepsini tek bir mesajla elde etmek mümkün değildir, bu nedenle bir istisna, az önce söylediğim gibi, farklı dillerde bulunabilecek olan son kullanıcı mesajına bazı tanımlayıcılar sağlaması gerekebilir.

Bağlantılı tüm soruları okuduğumda, bir istisna mesajının gerçekten bir son kullanıcı tarafından değil bir geliştirici tarafından okunması istendiği izlenimini edindim ... tek bir mesajın bir pasta olması ve onu yemesi gibi.


4
Burada akla gelen Programcılar hakkında sorulan iki soru daha var. Çiftleri olup olmadıklarından emin değilim, ama onları okumanız gerektiğini düşünüyorum ve belki de endişelerinizin bir kısmını veya tamamını ele alacaklar: İyi bir istisna mesajı nasıl yazılır ve neden birçok istisna mesajı faydalı bilgiler içermiyor? ?
Thomas Owens

2
@ThomasOwens İkisini de okudum ancak bir istisna mesajının alıcısına yönelik değiller. Genel olarak kullanıcılar hakkında konuşurlar ama kim o? Neyin yanlış gittiğini analiz etmesi gereken programlama veya geliştiriciler hakkında fikri olan yazılımın kullanıcısı mı? Mesaj yazarken kiminle konuşmam gerektiğini asla bilemiyorum.
t3chb0t

2
Bence burada iyi bir cevap, bu sorulardan herhangi birine veya ikisine birden başvurabilir, ancak bunlar çift kopyalardan uzaktır.
Monica

1
Bu neden dünya üzerinde kopya olarak kapatıldı? Bu diğer sorunun bir kopyası olsa bile (ki olmasa da), bu sorunun daha iyi bir cevabı var, yinelenen olarak işaretlenmiş bir diğeri olmalı.
Ben Aaronson

2
@MichaelT İstisna mesajlarının kullanıcılar için olduğunu varsaymadığınız sürece hala orada pek bir örtüşme görmüyorum
Ben Aaronson

Yanıtlar:


46

Bu mesajlar diğer geliştiriciler içindir.

Bu mesajların , uygulamada hata ayıklamalarına yardımcı olmak için geliştiriciler tarafından okunması beklenir . Bu iki şekilde olabilir:

  • Aktif hata ayıklama. Aslında kod yazarken ve ne olduğunu anlamaya çalışırken bir hata ayıklayıcı çalıştırıyorsunuz. Bu bağlamda, yararlı bir istisna, neyin yanlış gittiğini anlamayı kolaylaştırarak veya nihayetinde bir geçici çözüm önerdiğinde (bu isteğe bağlı olsa da) sizi yönlendirecektir.

  • Pasif hata ayıklama. Kod üretimde çalışır ve başarısız olur. Özel durum günlüğe kaydedilir, ancak yalnızca ileti ve yığın izini alırsınız. Bu bağlamda, yardımcı bir istisna mesajı hatayı hızlı bir şekilde lokalize etmenize yardımcı olacaktır.

    Bu mesajlar sıklıkla günlüğe kaydedildiğinden, oraya hassas bilgileri dahil etmemeniz gerektiği anlamına gelir (örneğin, uygulamanın hatalarını ayıklamak için faydalı olsa bile)

Örneğin, IOSecurityExceptionbir dosya yazarken atılan bir istisna türü sorun hakkında çok açık değildir: bir dosyaya erişim iznimiz olmadığı için mi? Ya da belki okuyabiliriz ama yazamayız? Ya da belki dosya mevcut değil ve orada dosya oluşturma iznimiz yok mu? Veya belki de kilitlenmiştir (umarım, istisnanın türü bu durumda farklı olacaktır, ancak pratikte, türler bazen şifreli olabilir). Ya da belki Code Access Security herhangi bir G / Ç işlemi yapmamızı engelliyor mu?

Yerine:

IOSecurityException: dosya bulundu ancak içeriğini okuma izni reddedildi.

çok daha açık. Burada, dizindeki izinlerin doğru ayarlandığını hemen biliyoruz (aksi takdirde dosyanın var olduğunu bilemeyiz), ancak dosya düzeyindeki izinler sorunludur.

Bu, ayrıca istisna türünde olmayan herhangi bir ek bilgi sağlayamazsanız, mesajı boş tutabileceğiniz anlamına gelir. DivisionByZeroExceptionmesajın gereksiz olduğu iyi bir örnektir. Öte yandan, çoğu dilin mesajını belirtmeden bir istisna atmanıza izin vermesi, farklı bir nedenden dolayı yapılır: ya varsayılan mesaj zaten mevcut olduğundan ya da gerektiğinde daha sonra üretileceğinden (ve bunun nesnesinden mesaj, "OOPly" kelimesi için mükemmel bir anlam ifade eden istisna tipine eklenmiştir. konuşma .

Teknik (genellikle performans) nedenlerden dolayı, bazı mesajların olması gerekenden daha fazla şifreli olduğunu unutmayın. .NET'ler NullReferenceException:

Nesne referansı bir nesnenin örneğine atanmadı.

faydalı olmayan bir mesajın mükemmel bir örneğidir. Yararlı bir mesaj şudur:

Nesne başvurusu product, çağrıldığında bir nesnenin örneğine ayarlanmadı product.Price.

Bu mesajlar son kullanıcılar için değil!

Son kullanıcıların istisna mesajları görmesi beklenmiyor. Asla. Her ne kadar bazı geliştiriciler bu mesajları kullanıcılara gösterseler de, bu durum düşük kullanıcı deneyimi ve hayal kırıklığı yaratıyor. Gibi mesajlar:

Nesne referansı bir nesnenin örneğine atanmadı.

Son kullanıcı için kesinlikle hiçbir şey ifade etmiyor ve ne pahasına olursa olsun kaçınılması gerekiyor.

En kötü durum senaryosu, istisnayı kullanıcıya fırlatan ve uygulamadan çıkan küresel bir deneme / yakalama yapmaktır. Kullanıcıları ile ilgilenen bir uygulama:

  • İlk etapta istisnalar ele alır. Çoğu, kullanıcıyı rahatsız etmeden idare edilebilir. Ağ kapalı mı? Neden birkaç saniye bekleyip tekrar denemiyorsunuz?

  • Bir kullanıcının uygulamayı istisnai bir duruma yönlendirmesini önler. Kullanıcının iki sayı girmesini ve birincisini ikinciye bölmesini isterseniz, birkaç saniye sonra onu suçlamak için neden kullanıcının ikinci durumda sıfır girmesine izin verdiniz ? Metin kutusunun kırmızı olarak vurgulanması (sayının sıfırdan farklı olması gerektiğini söyleyen yararlı bir araç ipucu ile) ve alan kırmızı kalana kadar doğrulama düğmesini devre dışı bırakmaya ne dersiniz?

  • Bir kullanıcıyı, hata yapmayan bir biçimde bir işlem yapmaya davet eder. Bir dosyaya erişmek için yeterli izin yok mu? Neden kullanıcıdan idari izinler vermesini veya farklı bir dosya seçmesini istemiyorsunuz?

  • Başka hiçbir şey işe yaramazsa, kullanıcının sıkıntılarını azaltmak için özel olarak yazılmış, kullanıcının neyin yanlış gittiğini anlamalarına ve nihayetinde sorunu çözmelerine yardımcı olacak ve gelecekte de hatayı önlemeye yardımcı olacak (yararlı olduğunda) yardımcı olan, yararlı bir hata gösterir.

    Sorunuzda, bir istisna dışında iki mesajınız olmasını önerdiniz: geliştiriciler için teknik ve son kullanıcılar için olan. Bu, bazı küçük durumlarda geçerli bir öneri olsa da, çoğu istisna, kullanıcılar için anlamlı bir mesaj üretmenin mümkün olmadığı bir düzeyde üretilir. Al DivisionByZeroExceptionve biz olmasını istisna engelleyemedi ve kendimizi işleyemez düşünün. Bölünme gerçekleştiğinde, çerçeve (istisnayı fırlatan iş kodu değil, çerçeve olduğu için) bir kullanıcı için ne kadar yararlı bir mesaj olacağını biliyor mu? Kesinlikle hayır:

    Sıfıra bölünme gerçekleşti. [TAMAM]

    Bunun yerine, kişi istisnayı atmasına izin verebilir ve daha sonra, iş bağlamını bildiğimiz ve son kullanıcıya gerçekten yardımcı olmak için buna göre davranabileceği daha yüksek bir seviyede yakalayabilir, böylece:

    D13 alanı, E6 alanındaki ile aynı değere sahip olamaz, çünkü bu değerlerin çıkarılması bir bölen olarak kullanılır. [TAMAM]

    ya da belki:

    ATP servisi tarafından bildirilen değerler yerel veriler ile tutarsız. Bunun nedeni yerel verilerin senkronizasyon dışı kalması olabilir. Gönderim bilgilerini senkronize edip tekrar denemek ister misiniz? [Evet Hayır]

Bu mesajlar ayrıştırma değildir

İstisna mesajlarının da programlı olarak ayrıştırılması veya kullanılması beklenmemektedir . Arayan kişi tarafından ek bilgiye ihtiyaç duyulabileceğini düşünüyorsanız, mesajın yanına istisnada yazın. Bu önemlidir, çünkü mesaj önceden bildirilmeksizin değiştirilebilir. Tür, arabirimin bir parçasıdır, ancak mesaj: istisnaların işlenmesi için asla ona güvenmeyin.

İstisna mesajını hayal edin:

Önbellek bağlantısına bağlanma 500 ms bekledikten sonra zaman aşımına uğradı. Sunucu zamanındaki düşüşü belirlemek için zaman aşımını artırın veya performans izlemeyi kontrol edin. Önbellekleme sunucusu için ortalama bekleme süresi 6 ms idi. son ay için 4 ms. geçen hafta ve 377 msn. son bir saat için.

“500”, “6”, “4” ve “377” değerlerini çıkarmak istiyorsunuz. Ayrıştırma yapmak için kullanacağınız yaklaşım hakkında biraz düşünün ve ancak daha sonra okumaya devam edin.

Fikrin var mı? Harika.

Şimdi, orijinal geliştirici bir yazım hatası buldu:

Connecting to the caching sever timed out after waiting [...]

olmalı:

                            ↓
Connecting to the caching server timed out after waiting [...]

Dahası, geliştirici ay / hafta / bir saatin özellikle ilgili olmadığını düşünüyor, bu yüzden ek bir değişiklik de yapıyor:

Önbellekleme sunucusu için ortalama bekleme süresi 6 ms idi. son ay için 5 ms. son 24 saat ve 377 msn. son bir saat için.

Ayrıştırma işleminize ne olacak?

Ayrıştırma yerine, istisna özelliklerini kullanıyor olabilir (veriler seri hale getirildikten sonra istediğini içerebilir):

{
    message: "Connecting to the caching [...]",
    properties: {
        "timeout": 500,
        "statistics": [
            { "timespan": 1, "unit": "month", "average-timeout": 6 },
            { "timespan": 7, "unit": "day", "average-timeout": 4 },
            { "timespan": 1, "unit": "hour", "average-timeout": 377 },
        ]
    }
}

Bu verileri şimdi kullanmak ne kadar kolay?

Bazen (.NET içinde olduğu gibi), mesaj bile kullanıcının diline çevrilebilir (IMHO, bu mesajları çevirmek kesinlikle yanlıştır, çünkü herhangi bir geliştiricinin İngilizce okuyabilmesi beklenir). Bu tür mesajların ayrıştırılması imkansızdır.


2
Son kullanıcı hakkında iyi bir nokta. Son kullanıcının güvenlik nedeniyle de istisna mesajları görmemesi gerektiğini eklerdim. Bir layman olmayan kullanıcı için bir hatanın tam olarak doğasını bilmek bir istismar sunabilir. Son kullanıcı, hatayı yalnızca yaptığı şey bağlamında bilmelidir.
Neil

1
@Neil: Bu biraz fazla teorik. Uygulamada, günlükleri kullanıcıdan gizlemenin yararı, çevrimiçi günlüklemenin karmaşıklığıyla ağır basmaktadır. Kullanıcı dostu yönü saymamak. Yeni Windows VM'nize Visual Studio yüklediğinizi hayal edin. Birden yükleme başarısız olur. Günlüklere gidip sorunu kendiniz teşhis etmeyi mi tercih edersiniz (Stack Exchange ve bloglar yardımıyla) veya Microsoft sorunu çözüp bir düzeltme yayınlayana kadar bekler misiniz?
Arseni Mourzenko

4
Herkesin "nesne başvurusu ..." iletisinin yararsız olduğunu bildiğini düşünüyorum. Bununla birlikte, asıl soru , jitterin istediğiniz mesajı üreten makinenin hangi kodunu oluşturmasını istersiniz? Bu alıştırmayı yaparsanız, mesajın istisnai olmayan tüm durumlara uygulanan çok yüksek bir performans maliyeti olmadan kolayca oluşturulamayacağını keşfedersiniz . Dikkatsiz bir geliştiricinin işini çok az kolaylaştırmanın faydası, son kullanıcıya verilen performanstan dolayı ödenmiyor.
Eric Lippert

7
Güvenlik istisnaları ile ilgili olarak: istisnadaki ne kadar az bilgi olursa o kadar iyidir. En sevdiğim fıkra, .NET 1.0'ın beta sürümünde "C: \ foo.txt dosyasının adını belirleme izniniz yok" gibi bir istisna mesajı alabileceğinizdir. Harika, bu ayrıntılı istisna mesajı için teşekkürler!
Eric Lippert

2
Son kullanıcıya asla ayrıntılı bir hata mesajı göstermemeye katılmıyorum. Oyun / yazılımımı başlatmamı engelleyen şifreli bir hata mesajı alıyorum, ancak çoğu zaman başıma geldi . Bu hata mesajı olmadan geçici çözümü bulmanın bir yolu olmazdı. Belki de "daha fazla ayrıntı" düğmesinin altındaki detayları gizlemek daha iyidir?
BlueRaja - Danny Pflughoeft

2

Bunun cevabı tamamen istisnaya bağlı.

Sorulacak en önemli soru "sorunu kim çözebilir?" Bir istisna, bir dosyayı açarken bir dosya sistemi hatasından kaynaklanıyorsa, bu mesajı son kullanıcıya vermek mantıklı olabilir. Mesaj, hatanın nasıl düzeltileceği hakkında daha fazla bilgi içerebilir. İşlerimde DLL'lerin yüklü olduğu bir eklenti sistemine sahip olduğumun kesin bir durumunu düşünebilirim. Bir kullanıcı yanlış eklentiyi yüklemek için komut satırında bir yazım hatası yaptıysa, altta yatan sistem hata mesajı, sorunu düzeltebilmeleri için gerçekten yararlı bilgiler içeriyordu.

Bununla birlikte, çoğu zaman yakalanmamış bir istisna, kullanıcı tarafından düzeltilemez. Bunların çoğu kodda değişiklik yapmayı içerir. Bu durumlarda, mesajın tüketicisi açıkça bir geliştiricidir.

İstisnaların istisnası, daha karmaşık bir durumdur çünkü istisnayı düzgün bir şekilde işleme koyma ve daha arkadaşça davranma fırsatınız vardır. Yazdığım bir betik dili, mesajı açıkça geliştirici için tasarlanan istisnaları attı. Ancak, yığın çözülmedikçe, komut dosyası dili içinden kullanıcı tarafından okunabilen yığın izleri ekledim. Kullanıcılarım çok nadiren mesaj yazabilir, ancak senaryolarındaki yığın izine bakabilir ve zamanın% 95'inin ne olduğunu çözebilirler. Kalan% 5'lik oran için, beni aradıklarında, sadece yığın izini değil, neyin yanlış olduğunu bulmama yardımcı olacak geliştiriciye hazır bir mesajını aldık.

Genel olarak, İstisna mesajını bilinmeyen bir içerik olarak kabul ediyorum. Uygulamalar hakkında daha fazla bilgi sahibi olan başka bir kişi daha yazılımımı istisna etti. Bazen bilinmeyen içeriğin bir son kullanıcı için faydalı olacağına dair bir fikrim var;


1
"Bir dosyayı açarken bir istisna dosya sistemi hatasından kaynaklanıyorsa, bu mesajı son kullanıcıya vermek mantıklı olabilir": ancak dosya sistemi hatasını attığınızda, içeriği bilmiyorsunuz: kullanıcı eylemi veya tamamen alakasız bir şey olabilir (uygulamanız, kullanıcının farkına bile varmadan bazı yapılandırmaların yedeğini alması gibi). Bu, bir istisna mesajını doğrudan göstermekten çok farklı bir hata mesajı gösteren bir try / catch bloğuna sahip olacağınız anlamına gelir .
Arseni Mourzenko

@MainMa İçeriği açıkça bilmiyor olabilirsiniz, ancak çok sayıda ipucu var. Örneğin, bir dosyayı açma sürecinde iseler varsa ve bunun istisnası "IOError: izin reddedildi" ise, kullanıcının 2 ve 2'yi bir araya getirip söz konusu dosyayı bulması makul bir ihtimaldir. Favori editörüm bunu yapıyor - sadece istisna metnini bir iletişim kutusunda kabartmasız çıktı olarak veriyor. Diğer taraftan, uygulamamı yüklüyordum ve bir sürü görüntü yüklerken "izin verilmeyen" olduysam, kullanıcının bilgilerle bir şeyler yapabileceğini varsaymak daha az makul olacaktır.
Cort Ammon - Monica

Amacınıza göre, bir kullanıcıya bir NullReferenceException göstermekte hiçbir zaman bir değer görmedim, bunun haricinde bu mesajı görüntülemenin yalnızca yazılımınızın nasıl kurtarılacağına dair bir ipucu olmadığını göstermesi dışında ! Bu istisna mesajı asla bir son kullanıcı için kullanışlı değildir.
Cort Ammon - Monica
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.