Autor Téma: Výnimky - praktické riešenie  (Přečteno 439 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Výnimky - praktické riešenie
« kdy: 23-06-2021, 17:45:09 »
Kód: Delphi [Vybrat]
  1. try
  2. FTable.UpdateTransaction.Rollback;  // Zámerné vyvolanie výnimky
  3. //FTable.UpdateTransaction := nil;  // Tento riadok nevyvolá výnimku. Prečo?
  4.   FTable.Post;
  5. except
  6.   on E: EDB_Exception do
  7.   begin
  8.       ShowMessage('EDB_Exception  '+E.Message);
  9.   end;
  10.   on E: EFDDBEngineException do
  11.   begin
  12.     ShowMessage('EFDDBEngineException  '+E.Message);
  13.   raise;
  14.   end;
  15.   on E: Exception do
  16.   begin
  17.     ShowMessage('Exception  '+E.Message);
  18.   end;
  19. end;
Dostanem sa až na riadok E: Exception. Preskočí aj EFDDBEngineException . Mal/chcel by som sa dostať na EDB_Exception.
Citace
Exception  [FireDAC][Comp][Clnt]-514. Transaction [fdtrReadWriteTransaction] must be active
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
Re:Výnimky - praktické riešenie
« Odpověď #1 kdy: 23-06-2021, 18:13:39 »
//FTable.UpdateTransaction := nil;  // Tento riadok nevyvolá výnimku. Prečo?
Protoze existuji nejake default transakce, ktere si ten FireDAC vnitrne vytvari - uz jsme to tu urcite probirali.
Citace
Dostanem sa až na riadok E: Exception. Preskočí aj EFDDBEngineException . Mal/chcel by som sa dostať na EDB_Exception.
No a copak ty vyvolas vyjimku typu EDB_Exception? Proto se v miste vyskytu exception, kde je nejvic informaci o provadene operaci, delava ta unifikace ruznych typu exception, ktere mohou emitovat ruzne subsystemy a o nichz nemas v jazyku jako Delphi zadne povedomi (u Javy se napr. musi deklarovat, jak exception to deklaruje a jake to zpracovava a pokud to neni konzistentni, tak to neprelozis) a ty se propaguji dal - prvni kod vyse.

Ruzne vetve za except ze zabyvaji jen konkretnim typem exception -> pokud vetev pro specificky typ neexistuje, spadne to do vetve s Exception (je to jako ELSE vetev u prikazu CASE).


Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Výnimky - praktické riešenie
« Odpověď #2 kdy: 23-06-2021, 18:18:59 »
Podľa oznamu sa vyvolá výnimka typu FireDAC. A ani tam neskončí!
Citace
No a copak ty vyvolas vyjimku typu EDB_Exception?
No, ja tam mám E: EAbstractException. To som zmenil dodatočne a tu som to neopravil. Tá by sa asi mala volať. Ale kedy a ako ???
« Poslední změna: 23-06-2021, 18:22:56 od Stanislav Hruška »
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
Re:Výnimky - praktické riešenie
« Odpověď #3 kdy: 23-06-2021, 18:29:48 »
Podľa oznamu sa vyvolá výnimka typu FireDAC. A ani tam neskončí!
Citace
No a copak ty vyvolas vyjimku typu EDB_Exception?
No, ja tam mám E: EAbstractException. To som zmenil dodatočne a tu som to neopravil. Tá by sa asi mala volať. Ale kedy a ako ???
No ano, tu vyjimku vyvola FireDAC a on si urci, co za typ to bude. A obecne, ten typ vyjimek muze skoro byt jakykoli, pokud neco selze napr. vlivem HW chyby. Jedine, co muzes predpokladat, ze to vzdy bude potomek Exception. Takze se musis podivat, co presne FireDAC emituje za typy, jestli maji nejakeho spolecneho predka a toho si ev. obslouzit a zkonvertovat do nejakeho vlastniho subsystemu pro zpracovani chyb.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Výnimky - praktické riešenie
« Odpověď #4 kdy: 23-06-2021, 18:32:56 »
A ako dosiahnem vyvolanie svojich výnimiek? Robil som to podľa Tvojej ukážky. Zjavne mi niečo chýba.
Ono tá chyba nie je práve chybou DB engine. To budem musieť urobiť ináč. Dám PK = 0.
« Poslední změna: 23-06-2021, 18:34:37 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
Re:Výnimky - praktické riešenie
« Odpověď #5 kdy: 23-06-2021, 18:37:34 »
To PK = 0 ma už dostalo do EFDDBEngineException.
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
Re:Výnimky - praktické riešenie
« Odpověď #6 kdy: 23-06-2021, 20:58:29 »
Hľadal som na internete a vidím to bledo. K vlastnej výnimke sa všade dostali pomocou MyException.Create().
V takom prípade to budem musieť zahrnúť do časti on E: EFDDBEngineException do ??? , čo sa mi veľmi nepozdáva.
Keď to tak zoberiem, tak EDB_Exception je akási popisne presnejšia náhrada za EFDDBEngineException.
To isté bude platiť aj pre ostatné výnimky.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2910
  • Karma: 106
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Výnimky - praktické riešenie
« Odpověď #7 kdy: 23-06-2021, 22:04:08 »
No ano, tu vyjimku vyvola FireDAC a on si urci, co za typ to bude. A obecne, ten typ vyjimek muze skoro byt jakykoli, pokud neco selze napr. vlivem HW chyby. Jedine, co muzes predpokladat, ze to vzdy bude potomek Exception. Takze se musis podivat, co presne FireDAC emituje za typy, jestli maji nejakeho spolecneho predka a toho si ev. obslouzit a zkonvertovat do nejakeho vlastniho subsystemu pro zpracovani chyb.


kdyby doslo na lamani chleba a na nic JINEHO neprisel, tak muze testovat zda E.message obsahuje [FireDAC] pro urceni ze je to z FireDac.

try
..
except
  on E: Exception do
    if Pos('[FireDAC]', E.Message) > 0 then
end;

Tedy jestli to spravne chapu o co tady jde.
Embarcadero MVP - Czech republic

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Výnimky - praktické riešenie
« Odpověď #8 kdy: 24-06-2021, 07:30:08 »
Citace
Takze se musis podivat, co presne FireDAC emituje za typy, jestli maji nejakeho spolecneho predka a toho si ev. obslouzit a zkonvertovat do nejakeho vlastniho subsystemu pro zpracovani chyb.
Aha, ako nepozorne či s neporozumením čítam diskusiu. Pozriem sa na to. Len nemám zdrojáky.
Citace
kdyby doslo na lamani chleba a na nic JINEHO neprisel, tak muze testovat zda E.message obsahuje [FireDAC] pro urceni ze je to z FireDac.
Kód: Delphi [Vybrat]
  1. try..except  on E: Exception do    if Pos('[FireDAC]', E.Message) > 0 thenend;

Tedy jestli to spravne chapu o co tady jde.
V podstate to chápeš správne. Len problém je v tom, že buď:
  • som v EFDDBEngineException a tam to je bezpredmetné, alebo
  • to dám inde a tým pádom preskočím EFDDBEngineException. A to nechcem
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
Re:Výnimky - praktické riešenie
« Odpověď #9 kdy: 24-06-2021, 07:33:10 »
Hľadal som na internete a vidím to bledo. K vlastnej výnimke sa všade dostali pomocou MyException.Create().
A co jsi hledal? :-O Jsme ve svete OOP, exception je objekt a ten vznikne tak, ze se vytvori jeho instance...

Citace
V takom prípade to budem musieť zahrnúť do časti on E: EFDDBEngineException do ??? , čo sa mi veľmi nepozdáva.
Budes muset zahrnout CO?

Citace
Keď to tak zoberiem, tak EDB_Exception je akási popisne presnejšia náhrada za EFDDBEngineException.
To isté bude platiť aj pre ostatné výnimky.
No aspon naznak, ze tusis, o co se jedna...

Nejde o presnejsi nahradu, ale o jednotny system zpracovani chyb v aplikaci, kdy si pomerne nesourody svet vyjimek z ruznych knihoven namapujes do vlastniho jednotneho subsystemu a pro jednotlive kategorie chyb si zajistis hodnoty, pri kterych k chybe doslo, abys dokazal pokud mozno urcit, co se kde stalo a proc.

Takze ty si nejdriv musis udelat navrh, jake chyby a jak potrebujes/chces v aplikaci zpracovavat a z toho ti vyleze nejaka taxonomie vlastnich vyjimek.

Pokud se jedna o vyjimky generovane konkretne o FireDAC, tak se podivej do FireDAC.Stan.Error, kde maji definovany vyjimky a jejich hierarchii:
Kód: Delphi [Vybrat]
  1.   System.SysUtils.Exception
  2.     Data.DB.EDatabaseError
  3.  
  4.       FireDAC.Stan.Error.EFDException
  5.         FireDAC.Stan.Error.EFDDBEngineException
  6.         FireDAC.Stan.Error.EFDDBArrayExecuteError
  7.  

A ty si musis urcit, jestli ti staci odchytavat jen EDatabaseError, nebo to potrebujes jemneji, kde napr. ta EFDDBEngineException uz obsahuje seznam detailu s polozkami TFDDBError.



Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3237
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Výnimky - praktické riešenie
« Odpověď #10 kdy: 24-06-2021, 07:37:09 »
  • som v EFDDBEngineException a tam to je bezpredmetné, alebo
  • to dám inde a tým pádom preskočím EFDDBEngineException. A to nechcem
Proc bys to mel preskakovat? Vyjimky, ktere umis rozlisit na zaklade tridy vyjimky vyjmenujes v except, kdyby ti stacila pro cele FireDAC jedna exception, tak ti staci EFDException. Ten test, co navrhuje Radek, bys dal jen do posledni vetve Exception, kde by ses snazil urcit, ze se vyjimka vztahuje k FireDAC a ne treba AV...

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Výnimky - praktické riešenie
« Odpověď #11 kdy: 24-06-2021, 08:28:32 »
  • som v EFDDBEngineException a tam to je bezpredmetné, alebo
  • to dám inde a tým pádom preskočím EFDDBEngineException. A to nechcem
Proc bys to mel preskakovat? Vyjimky, ktere umis rozlisit na zaklade tridy vyjimky vyjmenujes v except, kdyby ti stacila pro cele FireDAC jedna exception, tak ti staci EFDException. Ten test, co navrhuje Radek, bys dal jen do posledni vetve Exception, kde by ses snazil urcit, ze se vyjimka vztahuje k FireDAC a ne treba AV...
Na to som myslel.
Ako som už spomínal, nemám zdroje FireDAC (Delphi proffessional).Help ponúka toto:

  • EFDDBArrayExecuteError   EADDBArrayExecuteError sa používa ako položka popisu chyby poľa DML.
  • EFDDBEngineException   EDBEngineException je základná trieda výnimiek pre všetky chyby spojené s FireDAC DBMS.
  • EFDDBEngineExceptionClass
  • Výnimka EFDE   EFDException je základná trieda výnimiek pre všetky výnimky FireDAC.
  • EFDExceptionClass
  • TFDDBError   TFDDBError predstavuje chyby, varovania a správy FireDAC / DBMS pre triedu výnimiek EFDDBEngineException .
  • TFDDBErrorClass
Nevidím, žeby mi to malo nejako pomôcť.
Citace
Proc bys to mel preskakovat? Vyjimky, ktere umis rozlisit na zaklade tridy vyjimky vyjmenujes v except,
Lebo za tú riť neviem urobiť, aby mi fungovalo, napríklad po x.Post, on E: MyException do. Všetky ostatné vetvy fungujú ako majú. Viď založenie diskusie a tam uvedený kód.
Ak by som to dokázal, tak ostatné už dám nejako do kopy.
.
Pri chybe mi x.Post vyvolá EFDDBEngineException, alebo EDatabaseError. To by som svoju triedu musel definovať ako potomka EFDDBEngineException. Čo nie je žiaduce. Toto potrebujem prelomiť!
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
Re:Výnimky - praktické riešenie
« Odpověď #12 kdy: 24-06-2021, 09:36:04 »
Hm, už to vidím
Kód: Delphi [Vybrat]
  1.   except
  2.     on E: EFDDBEngineException do
  3.     begin
  4.       spLandlord_Flat_IU.Transaction.Rollback; //1. vzdycky odroluju, aby to nejaka dalsi exception nepreskocila
  5.       ILog.LogException('SP spLandlord has failed', E);
  6.       raise new XMyDBException.Create(MYDBERR_SP_LANDLORD_EXEC_FAILED, E);
  7.     end;
Takže predsa to musí byť v on E: EFDDBEngineException do
Predtým si samozrejme budem musieť ošetriť ostatné EFDDBEngineException. To jest tie, ktoré ja nemám v XMyDBException
« Poslední změna: 24-06-2021, 09:38:13 od Stanislav Hruška »
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
Re:Výnimky - praktické riešenie
« Odpověď #13 kdy: 24-06-2021, 09:47:09 »
Lebo za tú riť neviem urobiť, aby mi fungovalo, napríklad po x.Post, on E: MyException do.
Jak ti muze fungovat E: MyException do po Post, kdyz o tve MyException nic nevi  :o? Jak spravne pises, tak DB vrstva ti generuje bud chybu vazanou ke spolecne funkcionalite kolem TDataset v Delphi RTL, nebo specialni, pokud se tyka primo operaci ve vrstve FireDAC.

Ja uz nevim, co ti napsat: rekl bych, ze uz jsme tady za ta leta probrali exceptions ze vsech moznych i nemoznych pohledu  :-[

Ty se prece musis ridit tim, jak moc chces jednotlive chyby od sebe navzajem odlisovat. A jenom ty vis, co ta aplikace dela a jak si predstavujes, ze ji budes udrzovat tj. resit pripadne chyby a tomu adekvatne navrhnout nejaky zpusob obsluhy chyb.

U tebe nehrozi, ze bys to provozoval napr. v cizine, kde i kdybys prijel, tak te k produkcnimu systemu nepusti ani nenechaji na dalku pripojit, navic napr. se zavazkem problem do 24h odstranit, tak ti treba bude stacit to, co navrhli v Delphi tj. lokalne obslouzit zivotni cykly sdilenych prostredku pri vyjimce a nechat ji vypadnout do Application.OnException a tam to nejak centralne zmatlat. Konec koncu existuje pristup YAGNY aneb co te nepali nehas.



Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5840
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Výnimky - praktické riešenie
« Odpověď #14 kdy: 24-06-2021, 10:01:30 »
Citace
tak ti treba bude stacit to, co navrhli v Delphi tj. lokalne obslouzit zivotni cykly sdilenych prostredku pri vyjimce a nechat ji vypadnout do Application.OnException a tam to nejak centralne zmatlat. Konec koncu existuje pristup YAGNY aneb co te nepali nehas.
Vyzerá to, že mi to bude stačiť. Je to malý systém. Užívateľovi chcem zobrazovať minimum. A už vôbec nie celé texty chýb! Keď tak nad tým rozmýšľam, tak tá moja vlastná výnimka by v konečnom dôsledku nepriniesla nič navyše:
  • texty mi stačia originálne
  • ošetrenie výnimky bude vždy rovnaké
  • nepotrebujem pri výnimkách riešiť nejaké zložité stavy
  • predpokladám, že sa v podstate zaobídem aj bez vnorených výnimiek
Lepšie je urobiť si vlastné funkcie, ktoré použijem pri výnimkách. Aby som tam nemal zbytočne veľa kódu.
Ale v každom prípade som sa niečo naučil.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.