wyjątki kompletnie bez sensu

3

Funkcja niezbyt długa, w środku blok try, i sprawdzenie warunku który może często zachodzić, jak tylko user się pomyli.
Jeśli true to leci wyjątek standardowy (znaczy nie jakiejś specjalnej klasy)
W catch parę linijek niżej łapiemy wszytko , zakładamy że jest to powyższy wyjątek i pokazujemy userowi komunikat
Oczywiście prawdziwy wyjątek nie ma szans na sensowną obsługę....
Facepalm
Skoro lameriada nie umie pisać to może niech goto używa na to samo wyjdzie

5

Oczywiście, że wyjątki są złe. Nie zasługują na to, żeby być wyjątkowe. Oprogramowanie powinno być TOTALNE a nie pełne wyjątków. Aż zacytuje fragment Programowanie Funkcyjne dla Śmiertelników ze Scalaz

1.2 Programowanie czysto funkcyjne (Pure Functional Programming)

Programowanie Funkcyjne to akt tworzenia programów przy użyciu czystych funkcji (pure functions). Czyste funkcje mają trzy właściwości:

  • Totalność: zwracają wartość dla każdego możliwego argumentu (total)
  • Deterministyczność: za każdym razem zwracają tę samą wartość dla tego samego argumentu (deterministic)
  • Niewinność: brak (bezpośrednich) interakcji ze światem lub wewnętrznym stanem programu (inculpable)

Razem te właściwości dają nam bezprecedensową zdolność do rozumowania o naszym kodzie. Na przykład, walidacja wejścia jest łatwiejsza do wyizolowania z totalnością, caching jest możliwy, gdy funkcje są deterministyczne, a interagowanie ze światem jest łatwiejsze do kontrolowania i testowania, gdy funkcje są niewinne.

7

Wyjątki są całkiem spoko, tylko nie w każdym sofcie.
Najlepiej pasują do OOP.
Tylko wyjątki trzeba lubić, rozumieć i umieć stosować.
Jak gdzieś widzę hejt ekspertów to często mam wrażenie że brakuje u nich któregoś z tych elementów.

"Pokemon exception handling" jest znanym antypatternem.

1

Chyba tytuł wątku wybrałam trochę mylący, też uważam ze wyjątki mają sens, ale po prostu dobiło mnie że można użyć wyjątku żeby ... no cholera nie wiem nawet co myślał autor jeśli w ogóle myślał. Zamiast w miejscu sprawdzenia warunku zareagować to se rzucił wyjątek który obsłużył parę linii dalej

2

Istnieje podejście gdzie cokolwiek się nie wydarzy złego i nie takiego jak powinno to wywoływany jest wyjątek. Jest to styl gdzie ludzie uważają ify za zło i ich unikają jak ognia :)

1

Tylko po co nowy wątek skoro jest Programistyczne WTF jakie Was spotkały ? :P

6
Shalom napisał(a):

Tylko po co nowy wątek skoro jest Programistyczne WTF jakie Was spotkały ? :P

Bo on jest wyjątkowy :D

3

Sorki, musiałam się po prostu wygadać a tak mnie wnerwił ten kod że zupełnie zapomniałam o tym wątku, resztę genialnych pomysłów omawianych koderów opiszę już gdzie trzeba...albo wyjadę w Bieszczady

1

Może lepiej pokaż ten kod (lub jego przeróbkę w podobnym duchu).
Jeśli wyjątek jest faktycznie łapany w tej samej funkcji co rzucany to faktycznie jest to WTF i to niezależnie od paradygmatu programowania.
Jednak ja bym się na niego nie wnerwiał, bo zrobienie porządku z czymś takim to 20 sekund.

2

coś w tym stylu

void jakas_funkcja()
{
    try
    {
       wykonaj_cos()
       auto wczytany_plik =pobierz_plik();
       jeszcze_cos()
       if(!sprawdz(wczytany_plik))
               throw "niedobry plik";
       cos_jeszcze_wykonaj();
    }
    catch(...){
        pokaz_info("niedobry plik");
        return;
    }
}

0

Może w tym projekcie jest zasada by nie stosować pustego returna, a użycie else autorowi się nie spodobało, bo np za duży blok no i zrobił to tak, szczerze, bez intencji i całej podstawy to ja nie ocenił bym że ten kod jest głupi czy zły.

0
Miang napisał(a):

Sorki, musiałam się po prostu wygadać a tak mnie wnerwił ten kod że zupełnie zapomniałam o tym wątku, resztę genialnych pomysłów omawianych koderów opiszę już gdzie trzeba...albo wyjadę w Bieszczady

Też może trzeba zrobić kategorię porad psychologicznych :]

3
czysteskarpety napisał(a):
Miang napisał(a):

Sorki, musiałam się po prostu wygadać a tak mnie wnerwił ten kod że zupełnie zapomniałam o tym wątku, resztę genialnych pomysłów omawianych koderów opiszę już gdzie trzeba...albo wyjadę w Bieszczady

Też może trzeba zrobić kategorię porad psychologicznych :]

E... chyba nie trzeba. Jak dla mnie już sam fakt wsparcia ze strony innych użytkowników forum jest wystarczający,.

przyjaciele

4
mr_jaro napisał(a):

Istnieje podejście gdzie cokolwiek się nie wydarzy złego i nie takiego jak powinno to wywoływany jest wyjątek. Jest to styl gdzie ludzie uważają ify za zło i ich unikają jak ognia :)

No tylko że if przekłada się na instrukcję maszynową skoku warunkowego, a wyjątek angażuje maszynerię ze strony systemu operacyjnego…

Najgorzej jak trafimy na API pisane przez „wyjątkowego faszystę”: spotkałem się z biblioteką w której klasa prostego timera (do mierzenia czasu trwania operacji), była tak owyjątkowana że jej użycie było mordęgą:

// pseudokod
Timer timer = new Timer();
timer.GetResult(); // wyjątek! timer jeszcze nie wystartował.

timer.Start();
timer.Reset(); // wyjątek! resetujemy działający timer

timer.Stop();
timer.Stop(); // wyjątek! zatrzymujemy zatrzymany timer

timer.Start();
timer.Pause();
timer.Pause(); // wyjątek! pauzujemy spauzowany timer

timer.Start();
timer.Pause();
timer.Continue();
timer.Continue(); // wyjątek!

timer.Stop();
timer.Start(); // wyjątek! nie było Reset, albo trzeba było użyć Pause/Continue

itd.

1

To wstawię swój stary post ;)

2
Miang napisał(a):

coś w tym stylu

void jakas_funkcja()
{
    try
    {
       wykonaj_cos()
       auto wczytany_plik =pobierz_plik();
       jeszcze_cos()
       if(!sprawdz(wczytany_plik))
               throw "niedobry plik";
       cos_jeszcze_wykonaj();
    }
    catch(...){
        pokaz_info("niedobry plik");
        return;
    }
}

Jako, że to jest C++ i obsługa wyjątków jest ~40 razy wolniejsza od standardowego zwijania stosu, to nie przepuściłbym tego przez review.
Względy estetyczne/logiczne i brak wartości zwracanej też kwalifikują to jako bezsensowne rozwiązanie.

1

Wielkie dzięki wszystkim za pocieszanie ;) Próbowałam wytłumaczyć im co źle zrobili... ale bez rezultatów. Według autora wyjątki właśnie do tego służą. Rzuciłam paroma linkami ale wątpię czy coś czytają. Ma ktoś może namiary na jakiś hinduski tutorial o wyjątkach ? ;)
Ale ogólnie ifom przeciwni nie są, w miejscu gdzie świetnie by pasował switch zamiast tego pełno ifów

2
Miang napisał(a):

coś w tym stylu

void jakas_funkcja()
{
    try
    {
       wykonaj_cos()
       auto wczytany_plik =pobierz_plik();
       jeszcze_cos()
       if(!sprawdz(wczytany_plik))
               throw "niedobry plik";
       cos_jeszcze_wykonaj();
    }
    catch(...){
        pokaz_info("niedobry plik");
        return;
    }
}

Mogę się zgodzić, że if także by tam pasował, niemniej nadal nie mogę wyobrazić sobie przykładu kodu, gdzie rzucenie wyjątku pasowałoby jak ulał. Mam wrażenie, że wyjątki daje się na zasadzie "według naszej oceny w tym miejscu nie pasowałoby żadne działanie zamienne ani nawet zwrócenie jakiejkolwiek wartości, dlatego damy wyjątek".

1

@Silv: jakiekolwiek problemy z połączeniem między usługami, które normalnie muszą działać np. połączenie z bazą czy serwerem zarządzającym uprawnieniami. W takim wypadku czasem warto nawet położyć całą aplikacje wyjątkiem

0

@Silv: nie zawsze się da zwrócić wartość.

0

To miałem na myśli. Akcent jednak chciałem położyć na według naszej oceny. To znaczy – zanim @danek nie wspomniał o usługach, od których zawsze oczekuje się, że będą działać, to nie widziałem jakiegoś uogólnionego przypadku, jedynie subiektywną ocenę w każdej sytuacji.

3
Silv napisał(a):
Miang napisał(a):

coś w tym stylu

void jakas_funkcja()
{
    try
    {
       wykonaj_cos()
       auto wczytany_plik =pobierz_plik();
       jeszcze_cos()
       if(!sprawdz(wczytany_plik))
               throw "niedobry plik";
       cos_jeszcze_wykonaj();
    }
    catch(...){
        pokaz_info("niedobry plik");
        return;
    }
}

Mogę się zgodzić, że if także by tam pasował, niemniej nadal nie mogę wyobrazić sobie przykładu kodu, gdzie rzucenie wyjątku pasowałoby jak ulał. Mam wrażenie, że wyjątki daje się na zasadzie "według naszej oceny w tym miejscu nie pasowałoby żadne działanie zamienne ani nawet zwrócenie jakiejkolwiek wartości, dlatego damy wyjątek".

Ja błąd musi spropagować się przez wiele warstw aplikacji to wyjątki są po prostu bardzo wygodne.
Tak jak pisałem koszt zwijania stosu podczas wyjątków jest absurdalny, dlatego ograniczyłbym ich użycie do sytuacji literalnie wyjątkowych.

Jak ciekawska Komitet Standaryzacyjny C++ pracuje nad nowym rodzajem wyjątków (propagowania błędów).
Ma to działać bardzo podobnie do wyjątków w Swift. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r0.pdf

0

@MarekR22: piszesz wygodne, czyli dobrze położyłem nacisk? Kwestia osobistych preferencji?

Nie bardzo rozumiem, jaki związek ma koszt zwijania stosu z wyborem lub nie użycia wyjątków. Jaki to może być koszt? W jakich systemach może przeszkadzać?

4
Silv napisał(a):

@MarekR22: piszesz wygodne, czyli dobrze położyłem nacisk? Kwestia osobistych preferencji?

Nie bardzo rozumiem, jaki związek ma koszt zwijania stosu z wyborem lub nie użycia wyjątków. Jaki to może być koszt? W jakich systemach może przeszkadzać?

Taki związek, że jeżeli wiemy, że sytuacja będzie występowała często, to użycie wyjątku nie jest sytuacja wyjątkową, a wydajność spada na łeb, na szyję.
Dodatkowo, jeżeli wiemy że wyjątek ma być obsługiwany w metodzie wołającej, zamiast wyżej w hierarchii, to po co angażować mechanizm rozwijania stosu? Zwykła walidacja zwracająca wartość logiczną albo kod błędu by wystarczyła. Bo jeżeli szybkość wykonania ma spaść 40 razy, a ty tworzysz system, który ma obsługiwać jak najwięcej "transakcji" na sekundę, a co druga transakcja powoduje wyjątek, to jednak coś jest nie tak.

Ale w przypadku, gdy obsługa sytuacji nijak nie leży w kwestii kodu, gdzie ten stan wystąpił, to propagacja błędu bywa męcząca, bo albo zwracasz returnami w górę stosu, albo towarzysz jakiś mechanizm komunikacji pomiędzy metodą, która zaobserwowała błąd, a bytem odpowiedzialnym za obsługę błędu, co po prostu potrafi skomplikować kod. I wtedy wyjątki są ok.

Problem to nadużywanie wyjątków do zwykłej kontroli przepływu wykonania programu.

0

@nalik sytuacja gdy masz aplikację kilkunastowarstwową i pobierasz gdzieś coś z zewnętrznego api a kolejne warstwy mają na celu przetworzenie zapisanie itp tych danych. Samo pobieranie danych jest najniżej w hierarchii. Po jakimś czasie (nawet w trakcie testów na dev) okazuje się, że z tym api nie wszystko jest tak pięknie i zdarzają się dziwne rzeczy, więc zamiast przerabiać kilkanaście warstw robisz wyjątek chociażby po validacji otrzymanych danych. Czy to złe? W mojej ocenie absolutnie normalne rozwiązanie.

1
nalik napisał(a):
Silv napisał(a):

@MarekR22: piszesz wygodne, czyli dobrze położyłem nacisk? Kwestia osobistych preferencji?

Nie bardzo rozumiem, jaki związek ma koszt zwijania stosu z wyborem lub nie użycia wyjątków. Jaki to może być koszt? W jakich systemach może przeszkadzać?

Taki związek, że jeżeli wiemy, że sytuacja będzie występowała często, to użycie wyjątku nie jest sytuacja wyjątkową, a wydajność spada na łeb, na szyję.
Dodatkowo, jeżeli wiemy że wyjątek ma być obsługiwany w metodzie wołającej, zamiast wyżej w hierarchii, to po co angażować mechanizm rozwijania stosu? Zwykła walidacja zwracająca wartość logiczną albo kod błędu by wystarczyła. Bo jeżeli szybkość wykonania ma spaść 40 razy, a ty tworzysz system, który ma obsługiwać jak najwięcej "transakcji" na sekundę, a co druga transakcja powoduje wyjątek, to jednak coś jest nie tak.

Zgadzam się. Właśnie o to mi chodzi – dla mnie jest oczywiste, że jeśli ktoś jest świadomy negatywnego wpływu wyjątków na wydajność, to nie będzie ich tworzyć w systemach, w których ona jest celem. Z drugiej strony to też kwestia jasnego określenia priorytetów (czy na pewno w danym systemie liczy się wydajność).

Ale w przypadku, gdy obsługa sytuacji nijak nie leży w kwestii kodu, gdzie wyjątk poleciał, to propagacja błędu bywa męcząca, bo albo zwracasz returnami w górę stosu, albo towarzysz jakiś mechanizm komunikacji pomiędzy metoda, która zaobserwowała błąd, a bytem odpowiedzialnym za obsługę błędu, co po prostu potrafi skomplikować kod. I wtedy wyjątki są ok.

Problem to nadużywanie wyjątków do zwykłej kontroli przepływu wykonania programu.

Dzięki, trochę więcej już wiem. :)

0

Straszne pitu, pitu, piszecie. Kto raz nie przeczyta "Design By Contract" - Defensive Programing. Prawdopodobnie będzie całe życie się zastanawiał "Kurcze a czym się różni walidacja od rzucenia wyjątku, zapytam na 4P" :D.

Zgadzam się. Właśnie o to mi chodzi – dla mnie jest oczywiste, że jeśli ktoś jest świadomy negatywnego wpływu wyjątków na wydajność, to nie będzie ich tworzyć w systemach, w których ona jest celem. Z drugiej strony to też kwestia jasnego określenia priorytetów (czy na pewno w danym systemie liczy się wydajność).

Nie wy daje mi się, aby ktoś się kierował w tej kwestii wydajnością, raczej jest to efekt uboczny.

Wypychanie wszystkiego na monadzie jak Maybe z punktu widzenia OOP to też lameriada. Później okazuje się, że optional zwraca none i nie wiadomo dlaczego a testów nie ma no bo przecież jest Optional, więc co może się zepsuć. Poza tym samo wyrażenie języka domenowego, jak i modelu w tych przypadkach zwykle jest bardzo ubogie.

2

@Gworys: w jaki sposób użycie Optionala powoduje brak konieczności pisania testów?

0
danek napisał(a):

@Gworys: w jaki sposób użycie Optionala powoduje brak konieczności pisania testów?

Mozę nie uwierzysz, ale chodzą na tym świecie takie kwiatki, które uważają, że wyjątki i nulle to efekt zacofania programistycznego a jak się używa optionala to nie ma potrzebny pisać testów, które sprawdzają nulle i wyjątki.

2

Zamiast tesować nulle i wyjątki testujesz .isEmpty lub .getLeft() jeśli Either. Przecież samo zachowanie i odpowiedzialność programu się nie zmienia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1