Spring Boot’ta Hata Yönetimi (Exception Handling)

Metin Alnıaçık
3 min readJun 3, 2023

--

Başlıkta hata (error) kelimesini kullanmama rağmen burada kastettiğim şeyin istisna (exception) olduğunu belirterek başlayayım.

Spring Boot’ta hata yönetimi, anotasyonlar kullanılarak kolayca gerçekleştirilmektedir.

Hata yönetimini iki seviyede düşünebiliriz. Bunlardan biri sınıf seviyesidir. Diğeri ise tüm sınıfları kapsayan global seviyedir.

Bir örnek ile başlayalım.

  • Book adında bir sınıf oluşturuyoruz.
  • BookService adında bir servis sınıfı oluşturuyoruz.

Veri tabanından veri çekmek yerine init metodu ile kitap listesini dolduruyoruz.

Not: @PostConstruct anotasyonu sınıf oluşturulurken ilgili metodun (init) bir defa çalışmasını sağlar.

getBookByName metodu, kitap adı ile arama yapmamızı sağlar. Eğer ilgili isme ait bir kitap yoksa BookNotFoundException tipinde bir exception fırlatılır. Eğer biz bu fırlatılan exception’ı yakalamazsak ekranda kullanıcı için anlamsız bilgiler görüntülenecektir. Exception yakalamanın önemli bir faydası da farklı işlemleri de yapabiliyor olmamızdır. Örneğin, yakaladığımız exception log’unu kaydedebiliriz.

Exception’ı yakalamadığımızdaki ekran çıktısı aşağıdaki gibidir.

Exception Yakalanmadığındaki Ekran Görüntüsü

java adında bir kitap olmadığından exception fırlattı ve ekranda anlamlı olmayan bir exception mesajı gösterilmektedir.

İlk olarak, sınıf seviyesinde exception yakalama yapalım.

  • BookController adında bir controller ekliyoruz.

Exception’ı yakalayacak metot bookNotFoundException metodudur.
İlk olarak bu metodu ExceptionHandler anotasyonu ile işaretlememiz gerekmektedir.
İkinci olarak bu metot hangi exception sınıflarını yakalayacaksa onlar parantez içine yazılmalıdır.

Not: Bir metot, bir veya birden fazla exception sınıfını yakalabilir.

Örneğin: hem BookNotFoundException hem de NullPointerException tiplerini yakalamak istersek aşağıdaki gibi tanımlamamız gerekmektedir.

Not: birden fazla exception sınıfı olduğunda süslü parantez kullandığımızı unutmayın.

Az önceki endpoint’e istek attığımızda sonuç şu şekilde değişecektir.

Kitap Bulunamadı

Exception mesajını da yazdırmak istersek, şu şekilde düzenlemeliyiz.

Ekran görüntüsü aşağıdaki gibi olacaktır.

[xxx] adında bir kitap bulunamadı

Sınıf seviyesinde exception yönetimi bu kadar.

Şimdi de tüm sınıfları kapsayan global exception yönetimini inceleyelim.

BookController sınıfındaki Exceptionhandler anotasyonlu metodu, global excetion sınıfına taşıyoruz.

BookController sınıfının son hali aşağıdaki gibidir.

Global exception için GlobalExceptionHandler adında bir sınıf ekliyoruz.
@RestControllerAdvice anotasyonunu ekliyoruz.
Son olarak, yakalamak istediğimiz tüm exception tiplerini bu sınıfa ekliyoruz.

Kodda da görüldüğü üzere BookNotFoundException fırlatıldığında birinci metot, AuthorNotFoundException fırlatıldığında iki metot yakalayacaktır.

Kitap Adına Göre Arama Sonucu
Yazar Adına Göre Arama Sonucu

Son olarak yakalamadığımız/yakalayamadığımız hatalar için
Exception (Üst Sınıf) yakalayan bir metot yazarız. Bu sayede BookNotFoundException veya AuthorNotFoundException metotlarına düşmeyen exception’ların tümü bu metoda düşecektir.

GlobalExceptionHandler sınıfının son hali aşağıdaki gibidir.

Bu metodu test etmek için BookController sınıfına bir metot daha ekliyoruz.
Kodun hata alınan kısmında exception’ı fırlatmıyoruz (throw anahtar kelimesini kullanmıyoruz).

BookController sınıfının son hali aşağıdaki gibidir.

BookService sınıfının son hali aşağıdaki gibidir.

30. satırda, findFirst metodu çağrıldıktan sonra bir değer olup olmadığı kontrol edilmelidir. Direkt olarak get metodunu çağırdığımızda eğer kayıt bulunamadıysa NoSuchElementException tipinde bir exception fırlatacaktır. Fakat biz GlobalExceptionHandler sınıfında bu exception tipini yakalayan bir metot yazmadığımızdan dolayı Exception sınıfını yakalayan metot yakalayacaktır. Bunun sebebi, NoSuchElementException sınıfı Exception sınıfının alt sınıflarından biridir.

NoSuchElementException Örneği

Örneğin tamamına github adresimden ulaşabilirsiniz.

İyi günler,
Bol kodlamalar :)

--

--