Obsługa wyjątków

Część druga.

Tworzenie wsłasnego wyjątku.

Obsługa wyjątków może być napisana pod nasz projekt, dużo bardziej wyrafinowana niż przedstawione zostało w pierwszej części artykułu. Dla naszych potrzeb możemy tworzyć własne wyjątki. Po co tworzyć nowe wyjątki? Weźmy nasz przykład, gdzie rzucamy wyjątkiem IllegalArgumentException. Wyjątek ten jest bardzo ogólnym wyjątkiem. W programie możemy mieć wiele miejsc, które rzucają właśnie nim.

Napiszmy bardzo prostą klasę i nazwijmy ją CustomerNotFoundException.

public class CustomerNotFoundException extends Exception {

   public CustomerNotFoundException(String message) {
       super(message);
   }
}

Nasza klasa dziedziczy po klasie Exception i przenosi poprzez super(message) pole z tej klasy. Wzbogacając naszą klasę o możliwość definiowania własnego przekazu.

Podmieniamy poprzedni wyjątek na nasz i otrzymujemy:

public Account generateNewAccountForCustomer(Customer customer, Money 
   money) throws CustomerNotFoundException {
           if (!(customer.getName() == null)) {
               return new Account(money, customer);
           } else {
               throw new CustomerNotFoundException("Customer does not exists");
       }
   }

Oczywiście w metodzie main() klasy Main musimy też podmienić to co “łapiemy” czyli w bloku catch użyć nazwy naszego wyjątku.

Tłumaczenie jednego wyjątku na inny.

Zapewne już widać, że przekazujemy nasz rzucony wyjątek w “górę” w hierarchii kodu. 
Dobrą praktyką jest używanie własnych definicji wyjątków (jak to zrobiono powyżej), jednak przechodząc wyżej powinniśmy używać wyższego poziomu abstrakcji wyjątku. Możemy to zrobić tłumacząc nasz wyjątek na inny np. na IllegalArgumentException.

Aby to osiągnąć zmieniamy blok try-catch w klasie main() w nasjtępujący sposób:

try {
   Account account = accountFactory.generateNewAccountForCustomer(customer, new Money(BigDecimal.valueOf(2500)));
   System.out.println(account.toString());
} catch (CustomerNotFound
Exception e) {
   logger.warning("Customer does not exists or not provided " + e);
   throw new IllegalArgumentException();
}

W bloku catch rzucamy nowym wyjątkiem (metoda main() musi dodać słowo throws CustomerNotFoundException do swojej definicji).

W wyniku otrzymujemy:

kwi 05, 2020 5:22:11 PM com.company.main.Main main
 WARNING: Customer does not exists or not provided com.company.domain.customer.CustomerNotFoundException: Customer does not exists
 Exception in thread "main" java.lang.IllegalArgumentException at com.company.main.Main.main(Main.java:06)  

Czegoś tutaj brakuje! Wiemy, że rzuciliśmy wyjątkiem ale nie wiemy w której linijce kody wystąpił błąd (rzucenie naszego wyjątku). Aby to uzyskać przekazujemy to co “wypluwa” z siebie nasz wyjątek “e” do wnętrza IllegalArgumentException.

...
catch (CustomerNotFoundException e) {
   logger.warning("Customer does not exists or not provided " + e);
   throw new IllegalArgumentException(e);
} 

i teraz otrzymujemy pełny obraz błędu jaki się pojawił:

kwi 05, 2020 5:24:09 PM com.company.main.Main main
WARNING: Customer does not exists or not provided com.company.domain.customer.CustomerNotFoundException: Customer does not exists
Exception in thread "main" java.lang.IllegalArgumentException: com.company.domain.customer.CustomerNotExistException: Customer does not exists at com.company.main.Main.main(Main.java:06)
Caused by: com.company.domain.customer.CustomerNotExistException: Customer does not exists at com.company.application.AccountFactory.generateNewAccountForCustomer(AccountFactory.java:04) at com.company.main.Main.main(Main.java:06)

Jak widać tworzenie i obsługa wyjątków wcale nie jest takie trudne. Należy trochę poćwiczyć i wiedzieć, gdzie się ich używa i jak się je przekazuje w programie. Pamietajmy, że obsługa wyjątków ma wiele zalet dla naszej aplikacji.

Umiejętność obłsugi wyjątków nie kończy się na powyższym. Dużo nowych technik jest potrzebnych do obsługi zapytań w aplikacji webowej. O tym w przyszłych wpisach. Zostańcie z Lekcjami Kodu!

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *