Autor Téma: Konkrétne riešenie výnimky - potvrdenie, zavrhnutie riešenia, návrhy  (Přečteno 504 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional

Teraz
Kód: Delphi [Vybrat]
  1. procedure TfrmsubVatRate.actPostExecute(Sender: TObject);
  2. begin
  3.   try
  4.     MyObject.DataOK;
  5.   except // on E: Exception do
  6.     Exit;
  7.   end;
  8. end;
  9. .
  10. function TWaterWarmthOW.DataOK: Boolean;
  11. begin
  12.   try
  13.     FCustomDB.PostRecord(True);
  14.     Result := True;
  15.   except
  16.     raise;
  17.   end;
  18. end;
  19. .
  20. procedure TCustomDB.PostRecord(AAutoCommit: Boolean);
  21. begin
  22.   try
  23.     FTable.Post;
  24.   except
  25.     on E: EFDDBEngineException do
  26.     ...
  27.     on E: EDatabaseError do
  28.     ...
  29.     on E: Exception do
  30.     ...
  31.   end;
  32. end;
  33.  
Takto by to malo byť správne
Kód: Delphi [Vybrat]
  1. procedure TfrmsubVatRate.actPostExecute(Sender: TObject);
  2. begin
  3.   MyObject.DataOK;
  4. end;
  5. .
  6. function TWaterWarmthOW.DataOK: Boolean;
  7. begin
  8.   FCustomDB.PostRecord(True);
  9.   Result := True;
  10. end;
  11. .
  12. procedure TCustomDB.PostRecord(AAutoCommit: Boolean);
  13. begin
  14.   try
  15.     FTable.Post;
  16.   except
  17.     on E: EFDDBEngineException do
  18.     ...
  19.     on E: EDatabaseError do
  20.     ...
  21.     on E: Exception do
  22.     ...
  23.   end;
  24. end;
  25.  
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 1234
  • Karma: 51
    • Verze Delphi: 10.3
Proč je TWaterWarmthOW.DataOK funkce? Její návratovou hodnotu netestuješ a nic jiného než true jí stejně nepřiřazuješ...

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Máš pravdu. Postačuje procedure. Najprv som si myslel, že budem potrebovať návratovú hodnotu. No po dokončení kódu som si to neoveril. Ale teraz som si overil, že nie. Nahrádza ju exit.
Ďakujem.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
No, to som si dal. Začal som to opravovať. Stihol toho dosť kým som narazil na konštrukciu
Kód: Delphi [Vybrat]
  1.   if not inherited then
  2.     Exit(False);
:'( Hlava ma začína celkom pekne zrádzať :(

W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 1234
  • Karma: 51
    • Verze Delphi: 10.3
No ještě je otázkou, jestli to nějak pokračuje, nebo za tím exitem je už stejně konec :) A taky jestli někdy někde kromě tohoto případu nastavuješ návratovou hodnotu na false...

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
No ještě je otázkou, jestli to nějak pokračuje, nebo za tím exitem je už stejně konec :) A taky jestli někdy někde kromě tohoto případu nastavuješ návratovou hodnotu na false...
To síce nie je predmetom témy, ale vysvetlím. Rodič (základná trieda) vykonáva automatickú prvotnú kontrolu údajov pre DB komponenty. Preto tam je if not inherited then. Ďalej už, v potomkoch, návratovú hodnotu nepotrebujem. No i tak ju poctivo nastavujem ;)  Najprv False až na konci funkcií True. Ak by sa náhodou v budúcnosti čosi zmenilo.
Téma sa týka try - except - raise
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3237
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Hmmm, tohle na me dela dojem, ze Te vyjimky vlastne obtezuji a chces docilit toho, abys je nemusel na top-level level akci obsluhovat - stejne timto zpusobem neobsluhujes vyskyt kazde vyjimky...

Ale k tomu je v Delphi ta podpora stylu "Clovece, pos*r se", kde docilis v podstate tehoz a jeste tak, ze pochytas kazdou exception, ke ktere v Application.Run dojde:

Kód: Delphi [Vybrat]
  1. // .dpr:
  2. ExceptionHandler := TExceptionHandler.Create;  //nebo to muze byt singleton
  3. Application.OnException := ExceptionHandler.HandleException;
  4.  
  5. // exceptionhandler.pas
  6. procedure TExceptionHandler.HandleException(ASender:TObject; AException:Exception);
  7. begin
  8.   self.ProcessException(ASender,AException);
  9. end;
  10.  
  11. procedure TExceptionHandler.ProcessException(ASender:TObject; AException:Exception);
  12. begin
  13.   try
  14.     if AException is EFDDBEngineException then
  15.     begin
  16.        ...
  17.     end
  18.     else if AException is EDatabaseError then
  19.     begin
  20.       ...
  21.     end
  22.     else
  23.     begin
  24.       ...
  25.     end;
  26.   except on E:Exception do
  27.     begin
  28.       Application.ShowException(E);
  29.     end;
  30.   end;
  31. end;

To ti umozni psat top-level handlery akci bez obzsluhy exception:
Kód: Delphi [Vybrat]
  1. procedure TfrmsubVatRate.actPostExecute(Sender: TObject);
  2. begin
  3.   MyObject.DataOK;
  4. end;

Ale zrovna tak:
Kód: Delphi [Vybrat]
  1. procedure TfrmsubVatRate.actPostExecute(Sender: TObject);
  2. begin
  3.   try
  4.     MyObject.DataOK;
  5.   except on E:Exception do
  6.     ExceptionHandler.ProcessException(self, E);
  7.   end;
  8. end;

ev. kdybys potreboval ruzne zpusoby osetrovani vyjimek tak kdyz si udelas dalsi metodu ProcessException2 pak:
Kód: Delphi [Vybrat]
  1. procedure TfrmsubVatRate.actPostExecute(Sender: TObject);
  2. begin
  3.   try
  4.     ...
  5.     MyObject.DataOK;
  6.     ...
  7.   except on E:Exception do
  8.     begin
  9.       ExceptionHandler.ProcessException2(self, E);
  10.       ...
  11.     end;
  12.   end;
  13. end;

« Poslední změna: 26-06-2021, 09:34:06 od pf1957 »

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Tu sa mi jedná o túto konkrétnu situáciu. Pri ostatných uvidím čo a ako. Predpokladám, že to bude v základe rovnaké.
Citace
Hmmm, tohle na me dela dojem, ze Te vyjimky vlastne obtezuji a chces docilit toho, abys je nemusel na top-level level akci obsluhovat - stejne timto zpusobem neobsluhujes vyskyt kazde vyjimky...
V uvedenom príklade to tak vyzerá.
Ja mám vlastne len pár situácií, kde potrebujem ošetriť výnimky:
  • Table.Post
  • Query.Open
  • Query.Execute(Query.Params.ArraySize, 0);
  • Práca s JSON súborom. Ale o to sa stará SuperObject
  • Ostatné súbory: licencie, certifikáty ... Všetko len načítanie
Vzhľadom na hore napísané som pri pokusoch o riešenie nateraz dospel k názoru, že mi existujúce výnimky poskytujú všetko čo potrebujem. Pre mňa patričný kód. Pre užívateľa viem zosmoliť jednoduchú správu. Maximálne budem potrebovať použiť vložené výnimky.
Citace
Ale k tomu je v Delphi ta podpora stylu "Clovece, pos*r se", kde docilis v podstate tehoz a jeste tak, ze pochytas kazdou exception, ke ktere v Application.Run dojde:
Application nechcem do toho nijako miešať. Nemyslím si, že to je dobrý nápad.
.
Moja úvaha:
Kód: Delphi [Vybrat]
  1. procedure TMy(sub)Form.actPostExecute(Sender: TObject);
  2. begin
  3.   MyObject.DataOK;
  4. end;
  5.  
Tu len zavolám funkciu objetku. Výnimka už je ošetrená. Preto pokladám try za zbytočné
Kód: Delphi [Vybrat]
  1. function MyObject.DataOK: Boolean;
  2. begin
  3.   Result := False;  //  Pridal som to pre istotu
  4.   FCustomDB.PostRecord(True);
  5.   Result := True;
  6. end;
  7.  
V týchto prípadoch vždy volám tú istú funkciu. V nej bude výnimka kompletne ošetrená. Preto opäť necítim potrebu try.
Kód: Delphi [Vybrat]
  1. procedure TCustomDB.PostRecord(AAutoCommit: Boolean);
  2. begin
  3.   try
  4.     FTable.Post;
  5.   except  //  Tu ošetrím všetky výnimky, oznam pre užívateľa. Prípadny log či zaslanie si oznamu výnimky
  6.     on E: EFDDBEngineException do
  7.     ...
  8.     on E: EDatabaseError do
  9.     ...
  10.     on E: Exception do
  11.     ...
  12.   end;
  13. end;
  14.  
Nikde inde neexistuje FTable.Post; Tu kompletne/defintívne ošetrím výnimku. Nie je kde vyššie poslať výnimku. Preto tu chýba raise.
Snáď to je z pohľadu Delphi logicky správne.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3237
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Snáď to je z pohľadu Delphi logicky správne.
Ne, spravne to neni. Ale uz mlcim.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Dobre, skúsim zistiť/premyslieť si to prečo!
Všetky príklady a teória čo som čítal o tom veľmi nepojednáva. Na ich základe som si myslel, že to je v poriadku.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Otázka: v 1 sa vždy vyvolá výnimka, ak sa výnimka objaví v 3?
1 - 3 sú kódy v prvom mojom príspevku nižšie
.
Edit: podľa tohto textu nie
Citace
Výnimku je možné vyvolať buď priamo v bloku try, alebo kódom, ktorý sa volá príkazmi v bloku try. To znamená, že ak kód v bloku try zavolá rutinu, ktorá nedefinuje svoj vlastný obslužný program výnimiek, potom všetky výnimky vyvolané v rámci tejto rutiny spôsobia, že vykonanie prejde na obslužný program výnimiek spojený s blokom try.

« Poslední změna: 27-06-2021, 10:03:19 od Stanislav Hruška »
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional

Snáď to je z pohľadu Delphi logicky správne.
Ne, spravne to neni. Ale uz mlcim.
Tak som si znova prečítal všetko o výnimkách, čo je na stránke Embarcadera. Nijako neviem prísť na to, prečo to nie je správne.
Jediný potenciálne nebezpečný kód je v 3 - FTable.Post; Je to jediné miesto, kde mám try - except. Nikde inde sa tento blok nenachádza!
Ak výnimku ošetrím, tak je automaticky zničená. Nemám dôvod ísť do 2 či 1.
Nepredpokladám neošetrenú výnimku. Ak by aj taký stav nastal, tak v 2 či 1 nemám nič navyše, čo by mi v tom pomohlo.
Navýšenie výnimky či vnorenie výnimky je z môjho pohľadu úplne mimo veci.
.
Nájde sa niekto, kto mi to objasní? Prosím, nezaťahujte do toho nejaké hypotetické možnosti/stavy. Riešim len stav (1 - 2 - 3), ktorý som tu uviedol.
Ďakujem.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3237
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Navýšenie výnimky či vnorenie výnimky je z môjho pohľadu úplne mimo veci.
No spatne je prave ten tvuj pomyleny pohled na vyjimky, v tom ti zadny manual programovaciho jazyka nepomuze:

 - vyjimka je vyjimecny stav a nemela by byt soucasti aplikacni logiky => jeji vyskyt a pricina je v podstate nepredvidatelna vcetne indukovanych vyjimek aj.,
 - smyslem osetreni vyjimky je neumoznit alternativni control flow a obejiti obsluhy exceptions
 - Ty se to snazis buhvi proc osidit odchycenim vyjimek po jedine DB operaci -> kde mas rizeni transakci, co ti tam strasi argument AAutoCommit etc.
 - zkratka: kdyz uz to sidit, tak na centralni urovni, ktera poskytne robustni reseni, ktere bude fungovat i ve verzich aplikace a Delphi i+j


Ale ted uz skutecne prestavam cist prispevky Hruska+Exceptions

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Teraz mi to je konečne jasné! 8)
Citace
Ty se to snazis buhvi proc osidit odchycenim vyjimek po jedine DB operaci -> kde mas rizeni transakci, co ti tam strasi argument AAutoCommit etc.
To nie je pravda. Ja som sa len snažil na jednoduchom príklade pochopiť výnimky, vlastné výnimky a čo presne je vlastne to raise.
Vďaka Tebe a niekoľkých zaujímavých (pre mňa) informácií na internete v tom mám teraz už celkom jasno. Príklad: info - vždy na konci použite "else raise". Hneď mi bolo jasné prečo. Pravdepodobne by som tak nerobil.
PS:
Citace
Ale ted uz skutecne prestavam cist prispevky Hruska+Exceptions
Myslím si (a tajne dúfam), že to už nebude potrebné :)
Pre začiatočníkov a také nemehlá ako som ja prikladám na čo som vlastne narazil. Možno to niekomu pomôže.
« Poslední změna: 27-06-2021, 17:35:28 od Stanislav Hruška »
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.