Hata Yakalama | try-except

Şimdi sıra, daha önceki bloglarda değinip geçtiğim hata yakalama olayını anlamaya geldi. Normal şartlarda kullanıcının görmemesi gereken hata mesajları olur. Bunlar kimi zaman bir güvenlik açığı oluştururken kimi zaman sadece kullanıcıya yabancı gelir ve kullanıcı ürünümüzü kullanmak istemez. Bunlarla beraber bir kodu test ederken de bu metodu kullanabiliyoruz.

İlk önce nasıl yazıldığını görelim.

try: dedikten sonra girintili bir şekilde komutlarımızı yazıyor, sonrasında except: diyerek yine girintili bir şekilde komutlarımızı giriyoruz. Bu noktada Python try: kısmına yazdığımız kodları deneyecektir. Bu kodların çalışması sırasında herhangi bir hata gelirse bunu except: ile yakalayıp bizim istediğimiz ve belirlediğimiz hata mesajını gösterecektir. Ufak bir örnek yapalım.

Bu basit kod ile kullanıcıdan bir sayı istiyoruz. Normal şartlarda int(input()) dediğimiz için kesinlikle bir tam sayı girmesini istiyoruz. Çıktı kısmına baktığınızda ben, istenen değeri asd olarak vermişim yani bu bir tam sayı değil. Bu yüzden ValueError:... şeklinde bir hata aldık. Peki, yazılımdan hiç anlamayan biri bu hata mesajını görürse ne anlayabilir? Yüksek ihtimalle 15 saniye içinde programı kullanmaktan vazgeçecektir. Şimdi, aynı kodu try-except blokları ile yapalım.

Yine tam sayı girmedim ama bu defa hata mesajını görmek yerine "Sayı girmelisin" ifadesi geldi. Peki, aslında burada ne oldu?

Python, try: içerisindeki kodları denedi. Yani kullanıcıdan bir sayı istendi. Bu noktada kullanıcı tam sayı girmek yerine başka bir şey girdiğinde bir hata ile karşılaşacaktır. İşte tam olarak hatanın alındığı bu noktada except bloğu devreye giriyor ve hata mesajı yerine print("Sayı girmelisin.") kodu çalışıyor. Kullanıcı da bu sayede normal bir mesaj görmüş oluyor. try-except blokları bu şekilde.

Peki, tek bir kod içerisinde olası birkaç tane hata varsa bunları nasıl kontrol edersiniz? Aşağıdaki örneğe bakalım.

Biraz önce gördüğünüz gibi sayı yerine başka bir şey girdiğimde ValueError isminde bir hata alıyorum. Aynı zamanda programı CTRL + C kombinasyonu ile sonlandırdığımda KeyboardInterrupt kodlu hatayı alıyorum. Önceki bloglardan hatırlarsınız; exit() dediğimizde içine verdiğimiz değerler aslında durum kodlarıdır. Aynı şeyi burası için de düşünebilirsiniz. Birden fazla hata çeşidimiz var ve bu hatalar tek bir kod içerisinde gerçekleşebilir.

Normal şartlarda sıradan bir şekilde bu sorunu çözebilirsiniz:

İlk kırmızı kutuda sayı girmedim ve except bloğu bunu algıladı. İkinci kırmızı kutuda CTRL + C kombinasyonu ile programı sonlandırdım ve hata mesajı almak yerine yine except sayesinde normal bir mesaj aldım. Demek istediğim şey şu: "Bir except bloğu ile birden fazla hatayı kontrol edebilirsiniz."

Ancak belli bir hatanın alınması durumunda özel bir işlem yapılmasını isteyeceğiniz zamanlar olacaktır. Bununla beraber komplike programlarda kullanıcının yaptığı hatalara özel bilgilendirme mesajları vermek zorunda da kalabilirsiniz. İşte, bunun için except yapısı bize bir kolaylık sağlıyor ve hata koduna özel işlemler yapmamıza olanak tanıyor. Nasıl olduğunu görelim.

except dedikten sonra hata kodunu yanına yazarak bunu özelleştirebilir ve hata göre mesaj verebiliriz. Örneğin kullanıcı CTRL + C yaptığında KeyboardInterrupt hatası geliyor. Bunu istemiyorsanız except KeyboardInterrupt: deyip istediğiniz komutları verebilirsiniz.

Farklı bir hataya daha bakalım.

Normal şartlarda int bir değer ile string bir değeri toplayamıyoruz. Bunu daha önceki bloglardan biliyorsunuz. Bunun olması dahilinde çıkacak olan hata aşağıdaki gibidir.

Bu hata diyor ki: "int ve str tipindeki değerleri toplayamazsın." Biz zaten bu işi bildiğimiz için sorun yok ama kullanıcı bunları bilmek zorunda değil. Dolayısıyla buraya hemen bir try-except bloğu açıyoruz.

number ve string isimli değişkenleri try içerisine almamamın sebebi, onların denenmesine gerek olmamasıdır. Bizim asıl işlemimiz print(number + string) ifadesidir. Yani bir çıktı üretecek olan kodumuz bu. Dolayısıyla yalnızca bunu try içerisine alarak işlem yaptım.

Biz bu blokları koymasaydık yine TypeError hatası alacaktık ama try-except sayesinde daha anlaşılır bir mesaj verebiliyoruz. Şimdi, gerçek kodlardan örnekler verelim ve genel olarak nasıl hata yakalandığını görelim. Tamamı kendi GitHub sayfamda bulunan kodlardır. Lütfen kendi pratiklerinizi yapın.

NOT: Bu hata kodlarını ezberlemiyoruz. Yazdığımız kodu test ederken çıkan veya çıkması muhtemel hataları kontrol ediyoruz. Bunları zaten terminal üzerinden görebiliyoruz.

Aşağıdaki kodda bir sürü şey yapmış, KeyboardInterrupt hatasını yakalamışım.

Aşağıda, TypeError hatasını yakalamış ve kullanıcıyı uyarmışım.

Aşağıda, hem ValueError hem de KeyboardInterrupt hatalarını yakalamışım.

Aşağıda, işletim sisteminin destekleyemediği bir işlemin yapılması durumunda çıkan hatayı OSError ile yakalıyorum.

finally

Aslında try-except blokları içerisinde ele alınan bir blok daha vardır; finally bloğu. "Finally" kelimesinin anlamı "sonunda, en sonda" şeklindedir. Bu blok, try-except bloklarından sonra gelir ve her hâlükarda çalışır. Eğer bir try-except bloğunda kesinlikle çalışmasını istediğiniz bir kod varsa onu finally içerisine yazabilirsiniz. Hemen bakalım.

tyr-except-finally blokları arasında finally kısmının kesnilikle çalışacağını söylemiştim ve oldu. Bu kullanım size biraz saçma gelebilir ama sürekli olarak kontrol etmeniz gereken bir şey varsa finally blokları size oldukça yardımcı olacaktır.


Yayınlanma Tarihi: 2022-12-19 18:21:38

Son Düzenleme Tarihi: 2023-02-04 20:51:53