Jaki jest sens wyrzucać wyjątki (throw exception) ?

0

skoro to samo można obsłużyć ifami?

W R nie ma czegoś takiego, we wszystkich bibliotekach studenci lecą ifami, albo jak jakiś wirutuoz się trafi to czasem try {} catch {} użyje, dlatego nie rozumiem koncepcji Javy.

3

Tak, można obejść się bez wyjątków.
Nie, IFy nie starczą.

Wyobraź sobie metodę ```
String readFromFile(filename) throws IOException

Metoda zwraca Stringa - zawartość pliku.

Bez wyjątków musisz zwrócić Stringa i kod błędu. Do tego mieć gdzieś informacje co dany kod błędu oznacza (brak pliku, brak dostępu itd.). Czyli byś musiał zwrócić klasę, która ma różne elementy (String i ew. kod błędu).
Wyjątki są bardziej czytelne i bardziej eleganckie.

Coś jak z pętlą for i while. Możesz używać tylko jednej, ale czasami bardziej czytelnie jest użyć obydwu.


0

Wyjątki są bardziej czytelne i bardziej eleganckie.

Polemizowałbym.

0

a w praktyce to co częściej można spotkać w profesjonalnych aplikacjach korpo?

0

Wyjątki, nie wiem jak chcesz zrobić to na ifach. Wyjątek ma tą zaletę, że przerywa aktualne przetwarzanie i wyskakuje do najbliższej sekcji try/catch.
Wyobraź sobie wywołanie 100 metod w głąb i teraz na samym dole jest błąd.....

1

Wyjątki, nie wiem jak chcesz zrobić to na ifach.

Normalnie, dać Maybe albo Either, techniczne to nawet haskell ma try catcha dla "nieczystego" kodu ale w "czystym" kodzie nie ma sensu rzucania wyjątków.

0

Wyjątek może wylecieć bardzo wysoko. Obstawienie tego ifami czy za pomocą Either sprawdza się tylko dla czegoś takiego jak checked exceptions, bo te zwykle obsługuje bardzo blisko. Ale jak nagle stanie sie coś faktycznie niespodziewanego to zwykle chcemy wyskoczyć bardzo wysoko, a przepychanie Either czy jakiegoś errorcode przez 100 poziomów to chory pomysł.

0

Dokładnie. Co do wyjątków stosuję takie zasady:

  1. Gdy piszę korpo apkę (np. w Spring), rzucam sobie RuntimeExceptiony (np. Guava preconditions), checked najszybciej jak się da zamieniam na IllegalState. Następnie wykorzystuję jedno miejsce (ControllerAdvice / Filter), żeby chwycić te wyjątki i zalogować poprawnie ze StackTrace. Mam obsługę błędów pewną i w jednym miejscu, a mój kod produkcyjny jest prostszy.

  2. Gdy piszę mniejszą apkę to na poziomie głównej klasy łapię wszystkie wyjątki.

  3. Nigdy nie prowadzę logiki biznesowej (np. Błędy HTTP, walidację itp.) wyjątkami, ponieważ są one wolne. JVM traktuje je jako rzadkie przypadki.

Może jest ktoś mądrzejszy i robi inaczej chętnie się dowiem.

1

Od początku. W Javie mamy wyjątki weryfikowalne (checked) ponieważ taki był pomysł na język - mamy mechanizm chroniący przed błędami, które można przewidzieć.

Kolejna rzecz, to używanie wyjątków. Przez lata założenie, było takie, że wyjątek jest propagowany w górę, a na pewnym poziomie mamy jakiś mechanizm przechwytywania i obsługi wyjątków. Jakieś ExceptionHandler czy inne adnotacje ze springa. I to się sprawdzało do momentu, aż nie odkryliśmy, że takie zachowanie powoduje, że aplikacja bywa niestabilna. Dosypano do tego trochę koncepcji funkcyjnych i stwierdzono, że mechanizm wyjątków weryfikowalnych nie jest najlepszy.

Kolejnym etapem było wprowadzenie Either i Try, ale tu rozbiliśmy się o problem co mamy zwrócić gdy jednak mamy wyjątek. Tu wchodzą elementy związane z systemem typów i komponowaniem różnych elementów.

0
Julian_ napisał(a):

W R nie ma czegoś takiego

A stop() to niby czym jest?

0
Crude Monte Carlo napisał(a):
Julian_ napisał(a):

W R nie ma czegoś takiego

A stop() to niby czym jest?

to jest jak System.exit(0) z komunikatem.

0

Może inaczej. Co zrobi poniższy kod?

E <- simpleError("ERROR 1")

do_sth_internal <- function(){
  
  print("internal 1")
  
  if(TRUE) stop(E)
  
  print("internal 2")
  
}

do_sth_external <- function(){
  
  print("external 1")
  
  do_sth_internal()
  
  print("external 2")
  
}

tryCatch(
  do_sth_external(),
  error = function(E) "EDIT @insectoman: a teraz?",
  finally = print("Ultimate error handling script")
)
1

Ogólnie sprawa wygląda tak:
na pewno wyjątki są lepsze od zwracania jakiś dziwnych wartośći typu -1 , null czy cokolwiek.

Ale jednak CheckedException w Javie się nie sprawdziły:

  • są tak męczące w obsłudze, że programiści permanentie robią skróty typu
    catch (Exception e) {}

  • albo robią rethrow i kod konczy się tym , że prawie każda metoda ma "throws Exception" (tak, są tacy magicy),

  • w 95% przypadków obsługa optymalna wygląda tak
    catch (SiakisException e) {throw new RuntimeException(e)}

Czyli generalnie męczący boilerplate. (ale idea była ładna)

Dodatkowo wyjątki psują tak zwane referential transparency - czyli taką własnośc kodu, że wywołanie funkcji możesz zastapic przez wartość funkcji - liczbę.
Ta własność znakomicie ułatwia testowanie ( i nie potrzeba korzystać z mocków - nawet jak testujesz IO).

Dlatego jednak w miejsce Checked Exception lepiej użyć Try lub Either.
Nie tylko nie łamią referential transparency, ale dodatkowo dzięki monadycznym map i flatMap łatwo je można propagować.

Inna sprawa do RuntimeException - czyli te sytuacje kiedy wyrypał się system nie działa baza danych itp - czyli naprawdę wyjątkowe wyjatki.
Te są fajne i warto ich używać, a że nie trzeba deklarować to też nie brudzą w kodzie.
To są też wyjątki, których generalnie nie testujemy bo odpowiadają właśnie za sytuacje, które w zasadzie nie powinny mieć miejsca.

0

@jarekr000000: a co sądzisz o błędach walidacyjnych? Np użytkownik chce coś zrobić ale złego JSona wysyła na serwer - rzucać jakiś ValidationException? W sumie tutaj nie jest to sytuacja wyjątkowa, możemy się spodziewać że często użytkownik poda np id czegoś czego nie ma w bazie etc.

0

Jak mi uzytkownik wysyła złego JSona to odpowiadam mu np. 400 Bad Request - tu nie ma żadnego wyjątku w sensie javy.

0
jarekr000000 napisał(a):

Jak mi uzytkownik wysyła złego JSona to odpowiadam mu np. 400 Bad Request - tu nie ma żadnego wyjątku w sensie javy.

@jarekr000000 jak najbardziej, status HTTP będzie o tym mówił. Ale jakiś response też powinien być. Według mnie JSon z jakimś komunikatem, że "popełniłeś błąd" + do tego status 400

1

Jakieś artykuły / literatura na temat obsługi wyjątków? Coś też o Either? Poczytałbym o tym.

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