Jak wdrożyć obsługę błędów [zamknięte]

13

Mimo że od kilku lat programuję na poziomie profesjonalnym, nadal nie rozumiem w pełni obsługi błędów. Mimo że moje aplikacje działają dobrze, obsługa błędów nie jest zaimplementowana na poziomie profesjonalnym i stanowi połączenie wielu technik.

Moja obsługa błędów nie ma żadnej struktury. Chciałbym się dowiedzieć i zrozumieć, w jaki sposób jest wdrażany na poziomie profesjonalnym. To jest jedna dziedzina, w której brakuje mi wiedzy.

Kiedy powinienem skorzystać z wyjątków i kiedy powinienem zwrócić status powodzenia, aby sprawdzić w przepływie logiki? Czy można mieszać wyjątki i zwracać status?

Głównie koduję w C #.

James Jeffery
źródło
2
Dlaczego głosować w dół? Zadaję poważne pytanie dotyczące implementacji obsługi błędów i sposobu jej wykonania. Jeśli nie jest to najlepsze miejsce, aby zadać takie pytanie programistom, to gdzie jest? Naprawdę mnie to denerwuje, kiedy ludzie głosują w dół na takie pytania, ponieważ nie ma innego pytania. Jest to prawdopodobnie jedyne miejsce w sieci, w którym uzyskam wiarygodną odpowiedź i możliwe zasoby. Więc zamiast głosować w dół na pytanie, na które inni z pewnością będą Google, nie byłoby łatwiej odpowiedzieć na to pytanie?
James Jeffery,
6
Twoje pytanie jest bardzo szerokie. Być może możesz zawęzić zakres, powołując się na konkretne przykłady tego, w jaki sposób nie udało Ci się osiągnąć celów kodowania.
Andyz Smith
W Internecie znajduje się wiele artykułów na temat obsługi błędów: Spróbuj tego: msdn.microsoft.com/en-us/library/seyhszts.aspx
Nir Kornfeld

Odpowiedzi:

25
  1. Używaj wyjątków od wyjątkowych rzeczy, których nie możesz spodziewać się zbyt często, rzeczy, które wskazują, że coś idzie nie tak. Na przykład, jeśli sieć nie działa, jest to wyjątkowa rzecz dla serwera WWW. Jeśli baza danych jest niedostępna, oznacza to, że coś jest nie tak. Jeśli brakuje pliku konfiguracyjnego, prawdopodobnie oznacza to, że użytkownik się z nim pomylił.

  2. Nie używaj wyjątków do obsługi niepoprawnego kodu. Aby sprawdzić poprawność kodu, powinieneś użyć albo asercji, albo, w .NET Framework 4 i późniejszych, umów Code (które zastępują asercje i mają dodatkowe, szczególnie cenne funkcje).

  3. Nie używaj wyjątków w wyjątkowych przypadkach. Fakt, że użytkownik, poproszony o podanie numeru, wpisał „pies”, nie jest tak wyjątkowy, aby zasługiwał na wyjątek.

  4. Zachowaj ostrożność przy wyborze rodzajów wyjątków. W razie potrzeby twórz własne typy. Ostrożnie wybrał dziedzictwo, pamiętając, że złapani rodzice złapią również dzieci. Nigdy throw Exception.

  5. Nie używaj kodów powrotu dla błędów. Kody błędów można łatwo zamaskować, zignorować, zapomnieć. Jeśli wystąpi błąd, należy go obsłużyć lub propagować na wyższy stos.

  6. W przypadkach, w których oczekuje się, że metoda zwróci błąd, a błąd nie jest wyjątkowy, używaj wyliczeń, nigdy liczb błędów. Przykład:

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }

    Sens LoadOperationResult.ServerUnavailable, LoadOperationResult.ParsingErroritp jest dużo bardziej wyraźny niż, powiedzmy, pamiętając, że kod 12 oznacza, że serwer jest w dół, i kod 13 - że dane nie mogą być przetwarzane.

  7. Używaj kodów błędów, gdy odnoszą się do typowych, znanych przez każdego programistę pracującego w określonej domenie. Na przykład nie wymyślaj ponownie wartości wyliczania dla HTTP 404 Not Found lub HTTP 500 Internal Server Error.

  8. Uważaj na booleany. Wcześniej czy później będziesz chciał wiedzieć nie tylko, czy dana metoda się powiodła, czy nie, ale dlaczego. Wyjątki i wyliczenia są do tego znacznie silniejsze.

  9. Nie wychwytuj każdego wyjątku (chyba że jesteś na samym szczycie stosu). Jeśli złapiesz wyjątek, powinieneś być gotowy, aby go obsłużyć. Łapanie wszystkiego pokazuje, że nie obchodzi Cię poprawność działania kodu. Może to rozwiązać problem „Nie chcę teraz wyszukiwać, jak to naprawić”, ale prędzej czy później cię skrzywdzi.

  10. W języku C # nigdy nie wrzucaj wyjątków takich jak ten:

    catch (SomeException ex)
    {
        ...
        throw ex;
    }

    ponieważ łamiesz stos. Zrób to zamiast tego:

    catch (SomeException)
    {
        ...
        throw;
    }
  11. Staraj się pisać wiadomości o wyjątkach. Ile razy widziałem coś takiego throw Exception("wrong data")lub throw Exception("shouldn't call this method in this context"). Inni programiści, w tym ty sześć miesięcy później, nie mieliby pojęcia, jakie dane są nieprawidłowe i dlaczego lub dlaczego nie powinniśmy wywoływać jakiejś metody w kontekście, ani w jakim kontekście.

  12. Nie pokazuj użytkownikom komunikatów o wyjątkach. Nie oczekuje się ich od zwykłych ludzi, a często są nawet nieczytelne dla samych programistów.

  13. Nie lokalizuj komunikatów wyjątków. Przeszukiwanie dokumentacji zlokalizowanej wiadomości jest wyczerpujące i bezcelowe: każda wiadomość powinna być tylko w języku angielskim i angielskim.

  14. Nie skupiaj się wyłącznie na wyjątkach i błędach: dzienniki są również niezwykle ważne.

  15. W .NET nie zapomnij uwzględnić wyjątków w dokumentacji XML metody:

    /// <exception cref="MyException">Description of the exception</exception>

    Uwzględnienie wyjątków w dokumentacji XML znacznie ułatwia osobie korzystającej z biblioteki. Nie ma nic bardziej irytującego niż próba odgadnięcia, który wyjątek mógłby zostać zgłoszony metodą i dlaczego.

    W tym znaczeniu¹ obsługa wyjątków Java zapewnia bardziej rygorystyczne, lepsze podejście. Zmusza cię to albo do radzenia sobie z wyjątkami potencjalnie zgłaszanymi przez wywoływane metody, albo do zadeklarowania we własnej metodzie, że może zgłaszać wyjątki, których nie obsłużysz, czyniąc rzeczy szczególnie przejrzystymi.


¹ To powiedziawszy, uważam, że rozróżnienie między wyjątkami i błędami w Javie jest dość bezużyteczne i mylące, biorąc pod uwagę, że język sprawdził i odznaczył wyjątki. Na szczęście .NET Framework ma tylko wyjątki i żadnych błędów.

MainMa
źródło
Nauczyłem się z tego trochę cytatu. Czy mogę zapytać, skąd pochodzi ta lista? Witryna czy osobiste doświadczenie? Tak czy inaczej wyjątkowa praca (hehe ją dostaniesz?).
Shelby115
@ Shelby115: lista pochodzi, w kolejności: Stack Exchange, osobiste doświadczenie i Code Complete autorstwa Steve Mcconnell.
Arseni Mourzenko
Dziękuję @MainMa, to doskonała odpowiedź! Kiedy byłem na uniwersytecie, miałem kod ukończony, ale ktoś go ukradł. Nie przeczytałem tego.
James Jeffery,
@JamesJeffery: następnie pożycz drugie wydanie w bibliotece lub kup jedno: jest to jedna z niewielu książek o rozwoju, która jest całkowicie warta pieniędzy.
Arseni Mourzenko
@MainMa Właśnie zamówiłem w Amazon, dzięki: DI również posiadam Clean Code i całkowicie zapomniałem o rozdziale 7.
James Jeffery,
1

Myślę, że lista MainMa jest bardzo kompletna. Dodam tylko kilka własnych:

  1. Przeczytaj artykuł Erica Lipperta o tym, jak klasyfikuje wyjątki. Szczególnie ważne jest to, że nie wychwytuje wyjątków, które w rzeczywistości są błędami w twoim kodzie. Zamiast tego napraw kod!
  2. Jeśli wiesz, że może wystąpić wyjątek ORAZ możesz coś z tym zrobić, załatw go, ale ogranicz zakres próbowania i przechwytywania oczekiwanego wyjątku. Oznacza to, nie rób tego:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

Zamiast tego zrób to:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • Nie używaj wyjątków dla przepływu sterowania. Na przykład nie rzucaj wyjątku ClientNotFoundException w oknie dialogowym wyszukiwania (nie znaleziono klienta nie jest wyjątkiem w tej sytuacji) i oczekuj, że kod wywołujący wyświetli komunikat „Nie znaleziono wyników”, gdy to nastąpi.

  • Nie połykaj wyjątków!

  • Pamiętaj, że prawdziwa obsługa wyjątku może oznaczać tylko 3 rzeczy:

    1. Ponów operację. Obowiązuje tylko, jeśli problem jest przejściowy.
    2. Wypróbuj alternatywę.
    3. Powiadom kogoś o problemie. Ważne tylko, jeśli powiadomienie jest możliwe do wykonania, co oznacza, że ​​użytkownik może coś z tym zrobić.

    Jeśli żadna z tych opcji nie ma zastosowania, prawdopodobnie nie powinieneś złapać tego wyjątku. Należy go jednak zarejestrować, a następnie anulować operację lub zamknąć. Oczywiście zależy to od twoich wymagań w odniesieniu do poprawności vs odporności.

Mikrofon
źródło