Raise Exception - sposób na komunikowanie o błędach użytkownika

0

Siedzą tu "eksperci" którzy twierdzą że nie powinno sie w ten sposób informować użytkownika o błędzie, tylko zawsze powinno sie przechwytywać wyjątek i wyrzucać ewentualne okienko. Moim zdaniem jesteście w błędzie i sie nie znacie

3

Jak Ci się wydaje, dla Pani Helenki bardziej czytelne będzie okienko z napisem Wystąpił problem z aplikacją, przekopiuj poniższą treść i pokaż ją informatykowi czy Application raised an cośtamexception at 0xdeadbeef cośtam blablabla?

0

Po to sa różne klasy wyjątków żeby je właściwie obsługiwać. Samemu można dawać np. Raise EHumanReadableException i stosowny czytelny komunikat i te wyświetlać, a inne techniczne ewentualnie wysyłać emailem z potwierdzeniem. Dzięki temu struktury TRY FINALLY ładnie działają i można konstruować ładny kod a nie kombinować z resultem przez 10 zagnieżdżonych funkcji.

Temat sie mnie trzyma, bo któryś chyba nawet z moderatorów tego działu Delphi tak tu krzyczał że to baaaardzo zły pomysł.

1

Tworząc klasę EHumanReadableException sprawiasz, że kod odpowiedzialny za logikę nagle musi także interesować się UI, co na ogół nie jest dobrym pomysłem.

O co chodzi Ci z tym kombinowaniem zwracania wyniku zagnieżdżonych funkcji?

0

chodzi o to że mam do wykonania szereg funkcji każda zależna od poprzedniej, i gdyby chcieć nie bazować nigdy na wyjątkach trzeba by pisać kod tak:

LRET:=FUNC1();
if LRET then
begin
 LRET:=FUN2();
 if LRET=false then
 begin
  Message('Błąd');
  Exit;
 end;
end;

zamiast jechać wprost

 FUNC1();
 FUNC2(); 

mając pewność że gdy FUNC1 wywali Raise Exception to w Fun2 nigdy nie wejdziemy.

0

No i to jest bardzo zła praktyka*, z której powodu powstały właśnie wyjątki.

Tyle że do czego się w tej chwili odnosisz?
W Twoim pierwotnym poście wspominałeś o innej sytuacji: wyjątki - ok; czytelne komunikaty błędów - nie ok.

* jeśli chodzi o czytelność kodu; z kolei takie C-style exceptions są za to znacznie wydajniejsze.

0

czyli dobrze rozumuje? Dobrze jest wywalać wyjątki zamiast co funkcje sprawdzać rezultat poprzedniej ?

heh to chyba namieszałem ,usuńcie temat bo chyba sie wykłóciłem niepotrzebnie :D

2

Każdy wyjątek powinien być przechwycony. Jeżeli wyjątek znajduje się w bloku try...except to i tak masz pewność że w razie wystąpienia wyjątku nie wykona się nic od miejsca wystąpienia aż po miejsce gdzie go przechwytujesz czyli sekcja except wspomnianego bloku.
Nick Hodges autor książki "Codding in Delphi" (Polskie wydanie pod tytułem "Programowanie w Delphi" http://helion.pl/ksiazki/programowanie-w-jezyku-delphi-nick-hodges,prodel.htm) i drugiego tomu "More Coding in Delphi" w swojej książce twierdzi ze nie należy używać wyjątków jako podstawowego sposobu sygnalizacyjnego jako złą praktykę podaje właśnie przykład:

type
TNormalBehaviorException = class(Exception);
...
begin
  SomeCodeThatDoesNormalThingsAndDoesntHaveAnyErrors;
  raise TNormalBehaviorException.Create('Something perfectly normal and expected happened');
end;

a jako dobrą przechwytywanie wybranych wyjątków

try
SomeCodeThatRaisesAnEConvertError;
except
  on E: EIBError do
  begin
    if E.ErrorCode = iSomeCodeIWantToCatch then
    begin
      //Kod obsługujący konkretny błąd
    end else
    begin
      raise; //Powtórne zgłoszenie wyjątku, jeżeli wystąpił inny błąd
    end;
  end;
end;

Autor też kładzie wyraźny nacisk na to aby jak najdokładniej informować użytkownika o błędzie a nie suche informacje z których szary użytkownik nic nie zrozumie.

1
JohnDoe2 napisał(a)

Siedzą tu "eksperci" którzy twierdzą że nie powinno sie w ten sposób informować użytkownika o błędzie [...]

W ten sposób, czyli w jaki? Przy okazji - jak chcesz o coś zapytać to po prostu zapytaj, a nie zaczynaj postu od obrażania użytkowników już w pierwszym zdaniu; Ten wątek już od pierwszego posta wygląda tak, jakbyś pozjadał wszystkie rozumy i chciał się upewnić, że wszyscy inni to debile i się nie znają;

[...] tylko zawsze powinno sie przechwytywać wyjątek i wyrzucać ewentualne okienko.

Tak, zawsze powinno się przechwytywać wyjątki i ewentualnie wyświetlać okienko z czytelną informacją; Nie można dopuścić do sytuacji, w której wyjątek nie zostanie obsłużony przez nasz kod, czego efektem będzie wyświetlenie systemowego okienka o treści takiej, jaką widzimy podczas debugowania programu; A przeciętny użytkownik nie wie czym jest Access Violation at address XXX, nie wie skąd się to wzięło i co ma z tym zrobić, więc rzucanie mu w twarz takim błędem to stanowczo zły pomysł;

Dzięki temu struktury TRY FINALLY ładnie działają i można konstruować ładny kod a nie kombinować z resultem przez 10 zagnieżdżonych funkcji.

Po to wymyślono bloki Try Finally/Except, aby wykluczyć konieczność budowania drabinek **If**ów i sprawdzania rezultatów funkcji w nich (lub też programowania liniowego z **Exit**ami), kosztem nieco mniejszej wydajności; Wywołania metod mogących rzucić wyjątkiem wrzuca się w blok finalizujący lub łapiący wyjątki i problem z głowy; Selektywna obsługa wyjątków zapewnia możliwość rozróżnienia typu błędu i np. wyświetlenia stosownego komunikatu plus ew. dodatkowe działania, zależne od złapanego wyjątku;

Temat sie mnie trzyma, bo któryś chyba nawet z moderatorów tego działu Delphi tak tu krzyczał że to baaaardzo zły pomysł.

W takim razie zacytuj słowa tego użytkownika; Masz z tym jakiś problem?

chodzi o to że mam do wykonania szereg funkcji każda zależna od poprzedniej, i gdyby chcieć nie bazować nigdy na wyjątkach trzeba by pisać kod tak:

[...]

Nie można nie chcieć bazować na wyjątkach, bo całe RTL i VCL/LCL na nich bazuje; Pewne podstawowe operacje można zredukować do obsługi błędów w sposób znany z WinAPI (np. obsługa błędów wejścia/wyjścia, kod błędu pozyskany za pomocą funkcji IOResult), ale to nieliczne odstępstwa od reguły;

czyli dobrze rozumuje? Dobrze jest wywalać wyjątki zamiast co funkcje sprawdzać rezultat poprzedniej ?

Tak konstruuje się kod od dobrych 20 lat - dobrze, że w końcu to zrozumiałeś; Zresztą nas się pytasz? Przecież wątek prowadzisz tak jakbyś wszytko wiedział, a my nic;

heh to chyba namieszałem ,usuńcie temat bo chyba sie wykłóciłem niepotrzebnie :D

Trudno, chciałeś się popisać, ale nie wyszło; Zacząłeś wątek jako cwaniaczek, skończyłeś go jako newbie.

0
furious programming napisał(a):

Tak konstruuje się kod od dobrych 20 lat - dobrze, że w końcu to zrozumiałeś;

Zacząłeś wątek jako cwaniaczek, skończyłeś go jako newbie.
teraz ty zabrzmiałeś jak cwaniaczek, jak gdybym był debilem i 20 lat główkował, a przecież na intuicje dobrze zakumałem temat.

nie to że obrażam, ale od zawsze w tym dziale waliło cwaniactwem :]

0

teraz ty zabrzmiałeś jak cwaniaczek, jak gdybym był debilem i 20 lat główkował, a przecież na intuicje dobrze zakumałem temat.

Pisząc "w końcu zrozumiałeś", miałem na myśli długość trwania tego wątku i liczbę twoich postów, w których zadałeś pytania; Jeśli nie zakapowałeś to trudno - następnym razem od razu zaznacz, aby pisać jak do dziecka;

nie to że obrażam, ale od zawsze w tym dziale waliło cwaniactwem :]

Tak, głównie ze strony anonimów, bezmyślnych hejterów i niedouczonych ignorantów; I to się zgadza, bo z reguły hejt w tym dziale czy cwaniactwo wychodzi spod palców anonimów, czym twój pierwszy post w tym wątku niewątpliwie jest;

Jeżeli nie masz już więcej pytań dotyczących wyjątków i nic sensownego do napisania to zakończmy ten wątek, bo tylko pogarszasz swoją sytuację.

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