Obsługa błędów

Kadu

Każda z metod w kodzie powinna zwracać informacje o ew. błędach oraz sprawdzać status operacji zwracany przez wywoływane przez nią metody. W tym dziale spróbujemy ustandaryzować sposób przekazywania statusu operacji, sposób reagowania na błędy zwrócone przez metody wywoływane, przekazywanie informacji o błędach użytkownikowi oraz pozostałe szczegóły.


Spis treści

Powszechnie stosowane metody zwracania informacji o błędzie

  • określona "nieprawidłowa" wartość zwracanego rezultatu, np. jeśli

metoda zwraca wartości typu wskaźnikowego w razie blędu zwraca wartość typu NULL, jeśli powinna zwrócić liczbę dodatnią, w razie błędu zwraca wartosc ujemną. Wady: brak informacji jaki dokładnie błąd wystapił (ew. dla drugiego przypadku mozna to zaimplementować, ale z pierwszym jest problem), jesli metoda zwraca dowolną wartość z danego typu, dowolna wartość liczbowa, sposób nie zadziała.

  • zmienna statyczna reprezentująca status ostatniej operacji. Wady: problem z wielowątkowością.
  • wyjątki (exceptions). Wady: binarka z obsługa wyjatków zajmuje dużo wiecej, Kadu np. w tej chwili jest kompilowane bez obsługi wyjatków. QT także nie jest raczej przeznaczone do pracy z wyjatkami.

Powszechnie stosowane metody powiadamiania uzytkownika o błędzie

  • okno dialogowe z informacja o wystapieniu bledu
  • informacja tekstowa wypisywana na konsoli lub zapisywana do pliku (log)

Warte uwagi jest to, ze obslugujac dane zdarzenie wewnatrz funkcji nie jestesmy pewni czy powinnismy wyswietlic okno dialogowe z informacja o bledzie czy tez tylko zwrocic odpowiedni rezultat. Jesli nie obsluzymy powiadomienia uzytkownika o bledzie to w wiekszosci miejsc w ktorych metoda ta bedzie wywolywana trzeba bedzie zaimplementowac ten mechanizm. Wiaze sie to z nadmiarem kodu, ktory w zasadzie robi to samo. W przedziwnym przypadku zas moga byc problemy jesli zechcemy w miejscu wywolania danej metody obsluzyc blad w inny sposob, np. jesli metoda pobierania pliku przez http zawiedzie a my w takim wypadku chcemy zainicjowac proxy i sprobowac ponownie to okienka z informacjami o bledach nie powinny byc pokazywane przez dana metode.

Propozycje metod zwracania informacji o błędzie w metodach Kadu

Po pierwsze kazda metoda powinna zwracac status wykonania. Mysle, ze dobrym i prostym sposobem bedzie przyjecie zalozenia, ze nawet proste, trywialne metody zwracaja status. Po prostu wszystkie. Najwyzej niektore beda zwracac zawsze status oznaczajacy sukces. Dzieki temu mozemy przyjac druga zasade, ze w kazdym miejscu w ktorym wywolujemy taka metode sprawdzamy poprawnosc jej wykonania. Jesli taka trywialna metoda zostanie zmieniona i zacznie zwracac jakies inne statusy nie bedzie trzeba zmieniac pozostalej czesci kodu. Mozemy wiec przyjac wzor deklaracji metody:

 <typ_oznaczajcy_status> nazwaMetody(<argument1>, <argument2>, ...);

Jesli status bedzie zwracany jako rezultat wywolania funkcji zachowamy wygodny sposob wywolywania funkcji ze sprawdzaniem rezultatu:

 if (!nazwaMetody(...))
 {
   ...
   <obsluga bledu>
   ...
 }

typ oznaczajacy status powinien zatem dac sie konwertowac do wartosci typu bool. Jest to wygodne. Dla uproszczenia przyjmijmy na razie, ze jest to wlasnie typ bool.

Bedziemy potrzebowac takze sposobu na przekazanie funkcji informacji o tym czy ma powiadamiac uzytkownika o wystapieniu bledu czy tez chcemy blad w calosci obsluzyc po stronie kodu wywolujacego metode. Przyjmijmy, ze bedzie to dodatkowy, ostatni argument. Mozemy zalozyc, iz najczesciej potrzebujemy graficznej obslugi bledow wewnatrz funkcji, wiec domyslnie argument ten bedzie ustawiony na prawde.

 bool nazwaMetody(<argument1>, <argument2>, ..., bool gui_err = true);

Jak bedzie wygladal wtedy kod obslugi bledow wewnatrz takiej metody? W miejscach gdzie uzywamy metod napisanych wedlug tego schematu:

 if (!nazwaMetody(..., gui_err))
 {
   ...
   <writting some debug information here>
   ...
   if (gui_err)
     MessageBox::wrn("Description of the error");
   return false;
 }

W pozostalych miejscach bedzie to wygladalo mniej wiecej tak (przyklad):

 int result = nazwaMetody();
 if (result < 0)
 {
   ...
   <writting some debug information here>
   ...
   if (gui_err)
     MessageBox::wrn("Description of the error");
   return false;
 }

Mam nadzieje, ze uda sie zrobic z tego jakies makro.

Wada tego rozwiazania i sprawa do przemyslenia jest to, ze najprostrza deklaracja w stylu:

 int count();

zmieni sie w cos takiego:

 bool count(int& nr_of_items, bool gui_err = true);

a prosty kod wywolujacy taka funkcje:

 printf("%i\n", count());

w cos takiego:

 int nr_of_items;
 if (count(nr_of_items))
   printf("%i\n", nr_of_items));

lub takiego:

 int nr_of_items;
 if (count(nr_of_items, false))
   printf("%i\n", nr_of_items));
 else
   printf("0\n");

mam wiec nadzieje, ze uda sie to jak najbardziej uproscic.

Aktualnie zalecana metoda zwracania informacji o błędzie w metodach Kadu

do uzupełnienia.


Osobiste