Utrzymuję to w prostocie.
Biblioteka ma podstawowy typ wyjątku rozszerzony z std ::: runtime_error (który z C ++ stosuje się odpowiednio do innych języków). Ten wyjątek pobiera ciąg komunikatu, abyśmy mogli się zalogować; każdy punkt rzucania ma unikalną wiadomość (zwykle z unikalnym identyfikatorem).
O to chodzi.
Uwaga 1 : W sytuacjach, gdy ktoś przechwytujący wyjątek może naprawić wyjątki i wznowić działanie. Dodam pochodne wyjątki dla rzeczy, które mogą być potencjalnie wyjątkowo naprawione w zdalnej lokalizacji. Jest to jednak bardzo rzadkie (pamiętaj, że łapacz raczej nie znajdzie się blisko punktu rzucania, więc naprawienie problemu będzie trudne (ale wszystko zależy od sytuacji)).
Uwaga 2 : Czasami biblioteka jest tak prosta, że nie warto nadawać jej własnego wyjątku i zrobi to std :: runtime_error. Wyjątek jest ważny tylko wtedy, gdy możliwość odróżnienia go od std :: runtime_error może dać użytkownikowi wystarczającą ilość informacji, aby coś z nim zrobić.
Uwaga 3 : W obrębie klasy zwykle wolę kody błędów (ale nigdy nie będą one uciekały przez publiczny interfejs API mojej klasy).
Patrząc na swoje kompromisy:
Kompromisy, które widzę, obejmują:
Więcej klas wyjątków może pozwolić na bardzo dokładne poziomy obsługi błędów dla użytkowników interfejsu API (podatne na konfigurację użytkownika lub błędy danych lub nie znaleziono plików)
Czy więcej wyjątków naprawdę zapewnia lepszą kontrolę ziarna? Pojawia się pytanie, czy kod przechwytujący naprawdę naprawia błąd na podstawie wyjątku. Jestem pewien, że zdarzają się takie sytuacje iw takich przypadkach powinieneś mieć inny wyjątek. Ale wszystkie wyjątki wymienione powyżej jedyną użyteczną poprawką jest wygenerowanie dużego ostrzeżenia i zatrzymanie aplikacji.
Więcej klas wyjątków pozwala na umieszczenie w wyjątku informacji specyficznych dla błędu, a nie tylko na ciąg znaków lub kod błędu
To doskonały powód do korzystania z wyjątków. Ale informacje muszą być przydatne dla osoby, która je buforuje. Czy mogą wykorzystać te informacje do wykonania pewnych działań naprawczych? Jeśli obiekt znajduje się wewnątrz biblioteki i nie można go użyć do wywierania wpływu na interfejs API, informacje są bezużyteczne. Musisz być bardzo konkretny, aby przekazane informacje miały przydatną wartość dla osoby, która może je złapać. Osoba przechwytująca to zwykle znajduje się poza publicznym interfejsem API, więc dostosuj informacje, aby można było z nimi korzystać w publicznym interfejsie API.
Jeśli wszystko, co mogą zrobić, to zarejestrować wyjątek, najlepiej po prostu rzucić komunikat o błędzie zamiast dużej ilości danych. Ponieważ łapacz zwykle buduje komunikat o błędzie z danymi. Jeśli zbudujesz komunikat o błędzie, będzie on spójny we wszystkich łapaczach, jeśli pozwolisz łapaczowi zbudować komunikat o błędzie, możesz otrzymać ten sam błąd zgłaszany inaczej w zależności od tego, kto dzwoni i łapie.
Mniej wyjątków, ale osadzanie kodu błędu, którego można użyć jako odnośnika
Musisz określić pogodę, kod błędu może być użytecznie użyteczny. Jeśli to możliwe, powinieneś mieć własny wyjątek. W przeciwnym razie użytkownicy będą musieli teraz wdrożyć instrukcje switch wewnątrz catch (co przeczy temu, że catch automatycznie obsługuje rzeczy).
Jeśli nie może, to dlaczego nie skorzystać z komunikatu o błędzie w wyjątku (nie trzeba dzielić kodu i komunikatu, że wyszukiwanie jest trudne).
Zwracanie kodów błędów i flag bezpośrednio z funkcji (czasami niemożliwe z wątków)
Zwracanie kodów błędów jest świetne wewnętrznie. Pozwala to naprawić błędy tam i wtedy, i musisz upewnić się, że naprawiłeś wszystkie kody błędów i uwzględniłeś je. Ale przeciekanie ich przez publiczny interfejs API to zły pomysł. Problem polega na tym, że programiści często zapominają sprawdzać stany błędów (przynajmniej wyjątek, niesprawdzony błąd zmusi aplikację do wyjścia z nieobsługiwanego błędu, który ogólnie spowoduje uszkodzenie wszystkich danych).
Wdrożono system zdarzenia lub wywołania zwrotnego po błędzie (unika rozwijania stosu)
Ta metoda jest często stosowana w połączeniu z innym mechanizmem obsługi błędów (nie jako alternatywa). Pomyśl o swoim programie Windows. Użytkownik inicjuje akcję, wybierając element menu. Generuje to akcję w kolejce zdarzeń. Kolejka zdarzeń ostatecznie przypisuje wątek do obsługi akcji. Wątek ma obsłużyć akcję i ostatecznie powrócić do puli wątków i czekać na kolejne zadanie. W tym przypadku wyjątek musi zostać wychwycony u podstawy przez wątek, którego zadaniem jest zadanie. Rezultat wyłapania wyjątku zwykle spowoduje wygenerowanie zdarzenia dla głównej pętli, co ostatecznie spowoduje wyświetlenie użytkownikowi komunikatu o błędzie.
Ale jeśli nie będziesz mógł kontynuować w obliczu wyjątku, stos się rozwinie (przynajmniej dla wątku).