Czy w zasadzie istnieją wyjątki, aby zapobiec awarii systemu?

16

Po drugie, zastanawiałem się, czy ktoś wiedział, jaka jest różnica między wyjątkami (w dziedzinie przepływu kontroli wyjątków) a wyjątkami (takimi jak używane w Javie).

Ale czy mają one zasadniczo chronić system przed awarią poprzez zakończenie programu użytkownika?

Mroczny Templariusz
źródło

Odpowiedzi:

29

Istnieją wyjątki , które umożliwiają obsługę wyjątków , co pozwala uniknąć awarii, ale bardziej ogólnie zapobiega niepożądanemu lub nieprzewidywalnemu działaniu systemu. Na przykład, jeśli mój program łączy się z bazą danych, limit czasu zwykle nie powoduje awarii systemu, ale jeśli zależałem od danych z bazy danych, wyjątek może pozwolić mi potraktować tę sytuację bez danych inaczej niż normalnie.

Powiedz domyślnie, że mój program wyświetla stronę danych na podstawie tego, co zostało zwrócone z bazy danych - no cóż, nie mam danych. Zamiast przedstawiać pomieszany widok lub kontynuować potencjalnie niepoprawną operację, mogę złapać ten wyjątek i wrócić do innej bazy danych, odczytać dane lokalne, poprosić użytkownika o dane lub w inny sposób przywrócić użytkownika lub system do bezpiecznego stanu (prawdopodobnie jednego nie spowoduje to od razu tego samego wyjątku!)

Ponadto w systemach, w których wkład użytkownika może być przyczyną / rozwiązaniem problemu, wyjątki mogą dać użytkownikowi szczegółowe i pomocne informacje na temat problemu. Zamiast zbyt częstego „Wystąpił nieobsługiwany wyjątek w ...” lub „Zastraszający komunikat o błędzie prosto z SQL” możesz powiedzieć użytkownikowi coś pomocnego lub co najmniej zrozumiałego, np. „Nie można połączyć się z zasobem B.”

Ben Brocka
źródło
5
Myślę, że to jest najdokładniejsza odpowiedź. Programy to działające maszyny stanów skończonych. Istnieją sposoby na uszkodzenie urządzenia poprzez wprowadzenie złych danych, które mogłyby spowodować jego nieprawidłowe działanie. Zgłaszane są wyjątki, aby temu zapobiec. Czasami maszyna może się zregenerować, ale czasem nie może.
Andy,
1
Czy nie mogę zrobić dokładnie tego samego z kodami błędów? Zwracasz błąd, a ja sobie z nim radzę.
mskw
16

Wyjątki zostały stworzone w celu uproszczenia obsługi błędów. Bez wyjątków logika obsługi błędów musi być rozłożona na aplikacje. Każda funkcja, która może spowodować błąd, musi w jakiś sposób zwrócić status błędu, a po każdym wywołaniu musi zostać sprawdzony błąd. Często osoba dzwoniąca nie może zrobić nic użytecznego w przypadku błędu i może sama zwrócić błąd. Połowa kodu aplikacji może być poświęcona obsłudze błędów. Taki kod jest wyjątkowo delikatny. Zbyt łatwo jest pominąć kontrolę błędów i spowodować awarię lub, co gorsza, zwrócić nieprawidłowe wyniki z powodu niezauważonego błędu.

Z wyjątkami błędy można sprawdzić tylko w punkcie, w którym można je naprawić. Większość kodu aplikacji można napisać prostoliniowo, ponieważ funkcje zwrócą użyteczną wartość lub zgłoszą wyjątek.

Kevin Cline
źródło
5

Wyjątkiem powinno być poinformowanie użytkownika o wyjątkowych okolicznościach. Jeśli coś pójdzie nie tak z systemem, program powinien wiedzieć i mieć możliwość właściwej obsługi *.

To powiedziawszy, nie, nie istnieje wyjątek zapobiegający „awarii” systemu. Wyjątkiem jest informowanie mnie o problemie. Postępowanie określa, czy system może się zawiesić.

Pamiętaj również, że wyjątek nie musi kończyć aplikacji, jak już powiedziałeś. Programista może obsłużyć wyjątek i poprawić go lub zmienić w znaczący błąd dla użytkownika.


* Korzystanie ze sprawdzonych wyjątków (wyjątków, które są zmuszane do złapania) jest trochę obolałe. Niektórzy (być może większość) deweloperów uważa, że ​​wymuszona obsługa wyjątków jest uciążliwa, niepotrzebna i po prostu zła praktyka.


źródło
2
Nie zgadzam się, ta definicja jest zbyt ograniczona. Użytkownik powinien zawsze wyświetlać tylko podzbiór wyjątków. Wyjątki dotyczą obsługi błędów, a rezygnacja i poinformowanie użytkownika jest zazwyczaj ostatnim krokiem, który nie powinien być normą. Niektóre systemy są przeznaczone do stosowania wyjątków w przypadku niektórych rodzajów sterowania przepływem zbyt, jak koniec iterable, EOF, itp
Jürgen Strobel
Jürgen, rozumiem i całkowicie zgadzam się z twoim komentarzem. „poprawione lub zamienione w jakiś znaczący błąd” - czy nie przekazuję tej myśli za pomocą tego stwierdzenia?
Tak, teraz jest znacznie lepiej.
Jürgen Strobel
Prawdopodobnie wyjątki nigdy nie powinny być pokazywane użytkownikom. (Warunki, które spowodowały ich wygenerowanie, mogą wymagać zgłoszenia w jakiś sposób użytkownikom, ale nie jako wyjątków.) Ale wyjątek jest zawsze lepszy niż program wykonujący tylko DIAF lub niespodziewane wyjście. („Za każdym razem, gdy próbuję posortować pocztę według nazwy nadawcy, klient poczty wychodzi cicho !!” Bez względu na to, jak czyste jest to wyjście, nadal jest błędne.)
Donal Fellows
2

Wyjątki umożliwiają nowoczesną obsługę błędów, dzieląc lokalizację błędu z procedury obsługi błędów. Czasami służy to również do kontroli przepływu.

Nieobsługiwane wyjątki powodują zakończenie programu. Ale nie różnią się one od poprzednich wyjątków, po prostu leniwy programista, który zapomniał dołączyć odpowiednie procedury obsługi błędów do każdej ścieżki, czyni je widocznymi dla użytkownika końcowego. Uważam, że program zakończony przez wyjątek uległ awarii tak samo, jak każdy inny nieoczekiwany koniec.

Systemy operacyjne są bardzo dobre w czyszczeniu zawieszonych procesów bez względu na to, w jaki sposób ulegały awariom, więc wyjątki nie zwiększają bezpieczeństwa systemu operacyjnego w żaden inny sposób niż zakończenie nieprawidłowo działających procesów i uwolnienie zasobów.

Jürgen Strobel
źródło
Istnieją ograniczenia dotyczące tego, co system operacyjny może wyczyścić. Ogólnie rzecz biorąc, system operacyjny nie może wiedzieć, czy jakieś trwałe zasoby (np. Pliki) muszą zostać wyczyszczone lub przywrócone, ani nie może wiedzieć, czy potrzebne jest jakieś czyszczenie zdalnego połączenia, poza zwykłym zamknięciem połączenia po stronie lokalnej.
8bittree
2

To jest bardzo proste.

  • Aby tylko zawiesić program, a nie cały system - mamy [dobre] systemy operacyjne.
  • Aby zawiesić program zamiast ignorować błąd krytyczny - mamy wyjątki.

Przed wynalezieniem wyjątków każda funkcja musiała zwrócić kod wyjścia (błąd / sukces), a każdy wynik lub wynik funkcji musiał zostać pobrany przez przekazanie wskaźnika do pamięci, aby został przez nią ustawiony.

Problem polegał na tym, że wielu programistów nie pamiętało / nie zawracało sobie głowy sprawdzaniem błędnych kodów wyjścia dla każdej funkcji, a zatem błędy krytyczne były czasami ignorowane, co prowadzi do dość niewyjaśnionych zachowań.

Dlatego postanowiono - gdy wystąpi błąd, którego nie wziąłeś pod uwagę, natychmiast się zawiesi! Obsługa wyjątków AKA.

Yam Marcovic
źródło
1

Wyjątki to po prostu mechanizm wykrywania błędów. Same w sobie nie są przydatne.

Ale wykrywając błąd, pozwalają uruchomić mechanizmy tolerancji na awarie, aby wyjść ze stanu błędnego, przechodząc do stanu wolnego od błędów (poprzedniego lub nowego). W ten sposób błąd nie jest propagowany do innych części systemu.

mouviciel
źródło
0

Istnieją wyjątki, aby oddzielić normalny przepływ programu (do czego program jest przeznaczony) od przepływu obsługi błędów (w jaki sposób program próbuje naprawić sytuację wyjątkową).

Dzięki temu kod jest bardziej przejrzysty i łatwiejszy w utrzymaniu.

Rozważ dwa fragmenty kodu:

try:
    do1()  # this is obvoiusly a normal
    do2()  # program flow
except:
    oups()  # this is exception handling code

W porównaniu do tego:

if foo():
    thing1()  # is this part of normal program flow?
else:
    thing2()  # or maybe this one? Or both? When?

Oczywiście można zastosować obsługę wyjątków, aby zapobiec awariom programu przez:

try {    // very bad code
    my();
    whole();
    ugly();
    application();
    here();
} catch (Throwable t) {
    // pretend it's ok
}

ale nie jest to powodem wyjątków we współczesnych językach programowania.

Możesz także użyć whilei breakzamiast tego, ifale nie do tego jest to whilei po co break.

Michał Šrajer
źródło
Właściwie radzenie sobie z „nienormalnym” przepływem kontroli jest właśnie wtedy , gdy goto i przerwa jego przyjaciela są najbardziej przydatne. Zaletą wyjątków jest to, że mogą przekraczać granice funkcji i że osoba dzwoniąca może określić, gdzie jest najbardziej odpowiedni, aby ją złapać.
hugomg
@hugomg: Kolejną dużą zaletą wyjątków jest to, że pozwalają one na czyszczenie zasobów i inne tego typu działania między miejscem, w którym wyjątek jest zgłaszany, a miejscem, w którym jest on obsługiwany.
supercat