Myślałem o tym i nie mogłem podać żadnego przykładu. Dlaczego ktoś miałby chcieć złapać wyjątek i nic z tym nie zrobić? Czy możesz podać przykład? Może jest to po prostu coś, czego nigdy nie należy robić.
exceptions
ysolik
źródło
źródło
Odpowiedzi:
Cały czas robię to z błędami konwersji w D:
To powiedziawszy, myślę, że wszystkie bloki catch powinny mieć coś w sobie, nawet jeśli to jest tylko komentarz wyjaśniający, dlaczego ignorujesz wyjątek.
Edycja: Chcę również podkreślić, że jeśli zamierzasz zrobić coś takiego, powinieneś być ostrożny, aby złapać tylko określony wyjątek, który chcesz zignorować. Robienie zwykłego starego
catch {}
jest prawie zawsze złą rzeczą.źródło
Jednym z przykładów, w którym moim zdaniem jest OK połknięcie wyjątku bez robienia czegokolwiek, nawet rejestrowanie wyjątku, znajduje się w samym kodzie rejestrowania.
Jeśli próbujesz coś zalogować i otrzymujesz wyjątek, niewiele możesz z tym zrobić:
Pozostawia to opcję „najmniejszego zła”, polegającą na cichym połykaniu, co pozwala aplikacji na wykonywanie głównej pracy, ale ogranicza możliwość jej rozwiązania.
źródło
Jeśli wyjątek zostanie zgłoszony przez operację, która i tak była opcjonalna, może nie być nic do zrobienia. Może się to nie przydać. W takim przypadku możesz po prostu chcieć go złapać i nic nie robić.
Jeśli to robisz, dołącz komentarz. Zawsze komentuj wszystko, co wygląda jak błąd (przegląd
switch
instrukcji, pustycatch
blok, przypisanie w stanie).Możesz argumentować, że nie jest to właściwe wykorzystanie wyjątków, ale to dotyczy innego pytania.
źródło
Puste
catch
bloki są zapachem kodu w większości języków. Główną ideą jest stosowanie wyjątków w wyjątkowych sytuacjach i nie wykorzystywanie ich do kontroli logicznej. Wszystkie wyjątki muszą być gdzieś obsługiwane.W wyniku zastosowania tego podejścia podczas programowania jednej konkretnej warstwy aplikacji masz kilka możliwości:
To tak naprawdę nie pozostawia miejsca na nic nie rób, puste
catch
bloki.ZMIENIONO DO DODANIA : załóżmy, że programujesz w języku, w którym zgłaszanie wyjątków jest normalnym sposobem kontrolowania logiki programu (jedna z alternatyw dla
goto
). Wówczas pustycatch
blok w programie napisanym w tym języku jest bardzo podobny do pustegoelse
bloku w tradycyjnym języku (lub w ogóle go nie maelse
). Uważam jednak, że nie jest to styl programowania zalecany przez społeczności programistów C #, Java lub C ++.źródło
W niektórych przypadkach Java wymaga obsługi wyjątku, który w żadnym wypadku nie może się zdarzyć. Rozważ ten kod:
Bez zepsucia platformy Java po prostu nie ma sposobu, aby spowodować ten wyjątek. Więc po co męczyć się z tym? Ale nie można po prostu pominąć klauzuli try-catch.
źródło
throw new Error(e)
aby mieć absolutną pewność, że niczego nie przegapiłem (lub nie zgłosiłem faktycznie uszkodzonej platformy).Zasadniczo nie. Możesz albo rzucić wyjątek na stos, albo zarejestrować, co się stało.
Jednak często to robię, gdy analizuję ciągi znaków i konwertuję na liczby (szczególnie w przypadku mapowania projektów, które są użyteczne raz i odrzucają różnorodność).
źródło
W niektórych przypadkach wyjątek wcale nie jest wyjątkowy; w rzeczywistości jest to oczekiwane. Rozważ ten przykład:
Ponieważ w java.lang.Process () nie ma metody isAlive (), jedynym sposobem sprawdzenia, czy wciąż żyje, jest wywołanie metody exitValue (), która zgłasza wyjątek IllegalThreadStateException, jeśli proces nadal działa.
źródło
Według mojego skromnego doświadczenia rzadko jest to dobra rzecz. Twój przebieg może się jednak różnić.
Niemal za każdym razem, gdy widziałem to w naszej bazie kodu, dzieje się tak, ponieważ wyśledziłem błąd, który ukrył zjedzony wyjątek. Innymi słowy, nie podając żadnego kodu, aplikacja nie może wskazać błędu ani wykonać innej akcji.
Czasami, na przykład, w warstwach API możesz nie chcieć lub nie możesz pominąć wyjątków, więc w takim przypadku staram się wychwycić najbardziej ogólne, a następnie je zapisać. Jeszcze raz, aby przynajmniej dać szansę sesji debugowania / diagnozy.
Zazwyczaj, jeśli musi być pusty, przynajmniej robię to, twierdzę, że coś się dzieje podczas sesji debugowania. To powiedziawszy, jeśli nie mogę sobie z tym poradzić, zwykle całkowicie je pomijam.
źródło
IMO jest jedno miejsce, w którym puste wyciągi połowowe są OK. W przypadkach testowych, w których spodziewany jest wyjątek:
źródło
Uważam, że istnieją pewne przypadki, w których uzasadnione jest posiadanie pustej klauzuli catch - są to przypadki, gdy chcesz, aby kod działał dalej, jeśli dana operacja się nie powiedzie. Myślę jednak, że ten wzór można łatwo nadużyć, dlatego każde użycie powinno być dokładnie zbadane, aby upewnić się, że nie ma lepszego sposobu na poradzenie sobie z nim. W szczególności nie należy tego nigdy robić, jeśli pozostawia on program w niespójnym stanie lub jeśli może to doprowadzić do awarii innej części kodu.
źródło
Nie wierzę w brak pewnego poziomu czujności w przypadku wystąpienia wyjątku - czy jednym z celów programowania nie powinno być ulepszanie kodu? Jeśli wyjątek wystąpi w 10% przypadków i nigdy się o nim nie dowiesz, wówczas wyjątek będzie zawsze taki zły lub gorszy.
Widzę jednak drugą stronę, że jeśli wyjątek nie powoduje rzeczywistej szkody w przetwarzaniu kodu, to po co narażać użytkownika na to. Rozwiązaniem, które zazwyczaj wdrażam, jest rejestrowanie go przez moją klasę loggera (czyli w każdej klasie, jaką kiedykolwiek piszę w pracy).
Jeśli jest to łagodny wyjątek, wywołuję metodę .Debug () mojego Loggera; w przeciwnym razie Logger.Error () (i (być może) rzut).
Nawiasem mówiąc, w mojej implementacji mojego programu rejestrującego wywołanie metody .Debug () spowoduje zarejestrowanie go tylko wtedy, gdy mój plik App.Config określi, że poziom dziennika wykonania programu jest w trybie debugowania.
źródło
Sprawdzanie istnienia jest dobrym przykładem użycia:
Innym przypadkiem
finally
jest użycie klauzuli:Proponuje się zezwolenie na pominięcie wiązania połowów w ECMAScript, które dotyczy tego i podobnych przypadków użycia.
Bibliografia
Propozycja ES: opcjonalne wiązanie połowu
python - Jak poprawnie ignorować wyjątki - Przepełnienie stosu
Obietnica anty wzory · petkaantonov / bluebird Wiki · GitHub
Wzorce zastępowania JavaScript
javascript - uruchom skrypt po załadowaniu bieżącego skryptu - Przepełnienie stosu
źródło
Jedyny raz, kiedy naprawdę potrzebowałem zrobić coś takiego, to klasa logowania dla aplikacji konsolowej. Istnieje globalny moduł obsługi catch najwyższego poziomu, który wysłał błąd do STDOUT, zarejestrował błąd do pliku, a następnie zamknął aplikację kodem błędu> 0.
Problem polegał na tym, że czasami logowanie do pliku kończyło się niepowodzeniem. Uprawnienia do katalogu powstrzymały cię przed zapisaniem pliku, plik został zablokowany, cokolwiek. Jeśli tak się stanie, nie będę w stanie obsłużyć wyjątku w taki sam sposób, jak gdzie indziej (złap, zarejestruj odpowiednie dane , zawiń lepszy typ wyjątku itp.), Ponieważ zarejestrowanie szczegółów wyjątku spowodowało, że program rejestrujący wykonał te same działania ( próba zapisu do pliku), który już się nie powiódł. Kiedy znów zawiodły ... Widzisz, dokąd idę. Wpada w nieskończoną pętlę.
Jeśli upuścisz niektóre bloki try {}, możesz skończyć z wyjątkiem pojawiającym się w oknie komunikatu (nie to, czego potrzebujesz dla aplikacji do cichej konfiguracji). Więc w tej metodzie, która zapisuje do pliku dziennika, mam pustą procedurę obsługi catch. Nie powoduje to zakopania błędu, ponieważ nadal pojawia się kod błędu> 0, po prostu zatrzymuje nieskończoną pętlę i pozwala aplikacji z wdziękiem wyjść.
Jest oczywiście komentarz wyjaśniający, dlaczego jest pusty.
(Zamierzałem to opublikować wcześniej, po prostu bałam się, że stanę w płomieniach zapomnienia. Ponieważ nie jestem jedyny ...)
źródło
Jest to odpowiednie w sytuacji, gdy trzeba wykonać pewną sekwencję bez względu na to, co ma najbardziej krytyczny element na końcu.
Na przykład. W kontroli ruchu komunikacja hosta ze sterownikiem. W sytuacjach awaryjnych istnieje szereg kroków przygotowujących do przerwania ruchu, zatrzymania generowania trajektorii, spowolnienia silników, umożliwienia przerw, wyłączenia wzmacniacza, a następnie należy zabić moc magistrali. Wszystko musi się zdarzyć sekwencyjnie, a jeśli jeden z kroków się nie powiedzie, pozostałe kroki muszą zostać wykonane mimo to, nawet przy akceptowanym ryzyku uszkodzenia sprzętu. Powiedz, że nawet jeśli wszystkie powyższe zawiodą, moc magistrali zabijania musi się zdarzyć.
źródło
Z wdzięcznym zamknięciem zasobów systemowych w celu odzyskania po błędzie
Na przykład. Jeśli używasz usługi w tle, które nie dostarcza informacji zwrotnej do użytkownika, może nie chcieć, aby popchnąć wskazanie błędu dla użytkownika, ale nie trzeba zamykać się zasoby są wykorzystywane w sposób wdzięku.
Najlepiej byłoby użyć funkcji catch w trybie debugowania, aby wykryć błędy i wydrukować je w konsoli lub w pliku dziennika w celu przetestowania. W środowisku produkcyjnym usługi w tle zasadniczo nie powinny przeszkadzać użytkownikowi, gdy zostanie zgłoszony błąd, więc wyjście błędu powinno zostać stłumione.
źródło