Nagłówek: Error.hpp
Elementy modułu: Error Module
Ten moduł to propozycja ujednoliconego mechanizmu obsługi błędów w programie z użyciem wyjątków C++. Można go używać w swoim kodzie. Używają go też niektóre inne moduły CommonLib, m.in. Stream i Files.
Klasą bazową wyjątku jest common::Error. Przechowuje ona stos stringów z komunikatami błedów. Motywację takiego podejście znajdziesz w moim artykule: "Problemy z obsługą błędów w kodzie C++", Adam Sawicki, Grudzień 2005. Pisząc w skrócie: obsługa błędów w programie jest niezwykle istotna dla efektywnego znajdowania i poprawnia błędów w programie oraz identyfikowania i rozwiązywania problemów podczas jego używania. Tymczasem ani komunikat błędu z miejsca jego wystąpienia - ten najniższego poziomu - na przykład "Nie można skonwertować liczby na łańcuch", ani komunikat z miejsca jego odebrania - ten nawyższego poziomu, na przykład "Nie można uruchomić programu" - nie daje pełnej informacji potrzebnej do zidentyfikowania problemu. Dopiero dokładanie na stos komunikatów błędów w czasie "przelotu" wyjątku a potem ich zdjęcie ze stosu w odwrotnej kolejności daje pełny obraz sytuacji, na przykład:
Nie można uruchomić programu Nie można wczytać pliku: Config.dat Błąd składni. Wiersz: 23, Kolumna: 8, Znak: 56 Nie można skonwertować liczby na łańcuch
Dostępne są makra do otaczania treści funkcji, aby wygodniej łapać błędy, dopisywać nowy komunikat do stosu i rzucać je dalej.
Klasa common::Error nie jest polimorficzna. Jedynym sensem istnienia jej klas pochodnych jest obecność konstruktora, który inicjalizuje błąd komunikatem z danymi charakterystycznymi dla danej biblioteki w razie potrzeby samemu pobierając dane tego błędu. Innymi słowy - zamienia błąd danej biblioteki na ujednolicony mechanizm obsługi błędów oferowany przez moduł Error. Dostępne są klasy:
void RobCos() { ERR_TRY; throw common::Error("Jakiś błąd"); ERR_CATCH_FUNC; } void WczytajKonfiguracje(const string &NazwaPliku) { ERR_TRY; RobCos(); ERR_CATCH("Nie można wczytać pliku: " + NazwaPliku); } void UruchomProgram() { ERR_TRY; WczytajKonfiguracje("Config.dat"); ERR_CATCH("Nie można uruchomić programu"); } void Test() { try { UruchomProgram(); } catch (const common::Error &e) { string Message; e.GetMessage_(&Message); MessageBox(g_MainWnd, Message.c_str(), "Mój program", MB_OK | MB_ICONERROR); } }
Przykład ten zwróci komunikat błędu podobny do tego:
[test.cpp,1611] Nie można uruchomić programu [test.cpp,1602] Nie można wczytać pliku: Config.dat [test.cpp,1593] void __cdecl RobCos(void) Jakiś błąd