Autor Téma: DB - trieda pre ošetrenie výnimiek  (Přečteno 3963 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6163
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #30 kdy: 23-05-2019, 08:48:58 »
Snáď som pochopil, ako by tie výnimky mali fungovať. Horšie to je s implementáciou. Momentálne rozmýšľa nad jedným problémom:
Kód: Delphi [Vybrat]
  1.   EDBAbstractException = class(EFDDBEngineException)
  2.    EDBException = class(EDBAbstractException)
Používam FireDAC a ten má vlastné ošetrenie výnimiek EFDDBEngineException. Bol by hriech to ignorovať. Ale ako to mám dostať do vlastného riešenia.
Kód: Delphi [Vybrat]
  1. EDBException = class(EFDDBEngineException)
Rozbije celý návrh. Pri EFDDBEngineException nemôžem použiť vnorenie výnimky. Neviem ktorú by som tam mal dať. Vnoriť EFDDBEngineException do vlastnej ešte pred jej vyvolaním je nezmysel.

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

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3343
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #31 kdy: 23-05-2019, 08:50:36 »
Vim co znamena verbose. Jedna vec je ze bych u metody cekal sloveso, tedy GetVerbose...,
Prefixem Get se zpravidla znaci gettery a to tady neni. Takze Verbose je tu v roli sloveso stejne jako je ReadXxxx, WriteXxx apod.

Citace
druha (podstatnejsi) ze zobrazujes v dialogu neco cemuz rikas ErrorCode. Od metody (Get)VerboseErrorCode bych totiz cekal vraceni nejakeho detailniho kodu chyby (ne zpravy pro BFU).
OK. S tim souhlasim, ale je to nejaka citace z diskuze, schvalne jsem se dival a u nas se to jmenu jen VerboseError

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3343
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #32 kdy: 23-05-2019, 09:05:49 »
Pri EFDDBEngineException nemôžem použiť vnorenie výnimky. Neviem ktorú by som tam mal dať. Vnoriť EFDDBEngineException do vlastnej ešte pred jej vyvolaním je nezmysel.
Tomu vubec nerozumim, proc bys nemohl pouzit vnorene vyjimky? Je pravda, ze normalni jazyky maji overload konstruktor, ktery jako parametr ocekava inner exception, takze se pise pri unifikaci error subsystemu neco takoveho a dela se to opakovane pri kazdem odchyceni vyjimky, aby se neztracely informace o tom, k cemu doslo.
Kód: Delphi [Vybrat]
  1. on e:ExceptionXyz do
  2.   begin
  3.    ...
  4.     raise MyException.Create(......, e);
  5.   end;
  6.  


Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6163
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #33 kdy: 23-05-2019, 09:21:32 »
Môj myšlienkový pochod:

  • Stlačím tlačidlo Post - tu je vlastná výnimka. Na EFDDBEngineException je podľa mňa veľmi skoro
  • Program vykoná TAble.Post - tu je EFDDBEngineException. Vnorenie nemôžem použiť, lebo neviem odkiaľ som to volal
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6163
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #34 kdy: 23-05-2019, 09:51:27 »
Už asi začínam starnúť ;)  Až keď to vidím napísane, tak mi došlo o čo ide.
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6163
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #35 kdy: 22-06-2021, 19:23:39 »

Tak som sa definitívne pustil do výnimiek. Vychádzam z návrhu pdf1957
Citace
no a pak bych v tom tvem kodu udelal treba:
Kód: Delphi [Vybrat]
  1.   spLandlord_Flat_IU.Transaction.StartTransaction;
  2.   try
  3.     spLandlord_Flat_IU.ExecProc;
  4.     spLandlord_Flat_IU.Transaction.Commit;
  5.   except
  6.     on E: EFDDBEngineException do
  7.     begin
  8.       spLandlord_Flat_IU.Transaction.Rollback; //1. vzdycky odroluju, aby to nejaka dalsi exception nepreskocila
  9.       ILog.LogException('SP spLandlord has failed', E);
  10.       raise new XMyDBException.Create(MYDBERR_SP_LANDLORD_EXEC_FAILED, E);
  11.     end;
  12.     else
  13.     begin
  14.       raise;
  15.     end;
  16.   end;
  17.  
Tu viem, kde to mám dať
  • V mieste volania spLandlord_Flat_IU.ExecProc; Ako to je v príklade. V takýchto prípadoch už väčšinou nemám kde poslať výnimku ďalej. Nemám predtým žiadne raise.
  • Table.Post; - Toto mám len v jedinej jednotke. Tu mám raise v mieste volania.
Citace
No a pak nekde dal:
Kód: Delphi [Vybrat]
  1. except
  2.   on E:XMYDBException
  3.     begin
  4.        myExc = XMYDBException(E);
  5.        case myExc.ErrorCode
  6.          MYDBERR_SP_LANDLORD_EXEC_FAILED:
  7.            begin
  8.               errMsg := myExc.VerboseErrorCode(Envi.GUICulture);
  9.               ShowErrorMessage(errMsg);
  10.            end;
  11.          else raise;
  12.        end;
  13.     end;
  14.   on E:EFDDBEngineException
  15.     begin
  16.       ...
  17.     end;
  18.   on E:Exception
  19.     begin
  20.        ...
  21.     end;
  22.  
V tomto prípade neviem prísť na to, kde má byť to "nekde dal". Je to súčasťou triedy XMyAbstractException = Exception;?
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline Jan Fiala

  • Hrdina
  • ****
  • Příspěvků: 256
  • Karma: 3
    • Verze Delphi: 10.4.1
    • PSPad editor
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #36 kdy: 22-06-2021, 19:44:42 »
Když už někde v kódu začneš transakci, tak bys ji měl na konci ukončit a v případě výjimky udělat rollback.
Tedy kromě toho Raise a dělání dalších věcí.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6163
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #37 kdy: 22-06-2021, 21:05:35 »
Když už někde v kódu začneš transakci, tak bys ji měl na konci ukončit a v případě výjimky udělat rollback.
Tedy kromě toho Raise a dělání dalších věcí.
To je samozrejmá vec. Mám to tak. Tu mi ide len o to umiestnenie toho druhého kódu. O ostatnom sa tu teraz nebavme.
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3343
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #38 kdy: 22-06-2021, 23:14:56 »
Tu mi ide len o to umiestnenie toho druhého kódu. O ostatnom sa tu teraz nebavme.
Smyslem prvniho kodu je
 - unifikovat vyjimku do jednotneho subsystemu osetrovani chyb v aplikaci
 - zaznamenat AMAP detailu o operaci, pri ktere k vyjimce doslo, protoze stack trace je v rade pripadu nedostacujici informace - vi se, kde k chybe doslo, ale nevi se, s jakymi hodnotami se operovalo.

Smyslem druheho kodu je s vyskytnuvsi se chybou udelat neco smysluplneho
 - zpravidla se dava do obsluhy akce v radici, kterou se neco spoustelo a nabizi se uzivatelil retry/skip/abort aj.
 - zaprotokolovani operace na vyssi urovni napr. do transakcniho logu pro pracovniky hot-line, ktere nezajimaji technicke detaily

Nekdy se vyjimka odchytava jeste nekde uprostred napr. abys propagoval informaci o iteraci, kdyz delas neco v davce a pri chybe chces umoznit preskocit jednu konkretni iteraci a pokracovat dal, je-li to mozne etc...

Je to treba resit pripad od pripadu, podle charakteru a slozitosti tasku, pri kterem se chyba vyskytla.



Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6163
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #39 kdy: 23-06-2021, 06:49:19 »
Ďakujem za pekné vysvetlenie.
  • Problém mám s tým, že pri Query je miesto spustenia a vyššia úroveň (tá tu neexistuje) to isté.
  • Pri Table najprv volám nejakú funkciu a až v nej volám DBCustom.PostRecord, ktorý to spustí (Post)
Nejako to už snáď vymyslím. Vychádza mi to tak, žeby som ten druhý kód mal mať vo svojej triede výnimky. Ale čo ďalšie prípadné výnimky?
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3343
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:DB - trieda pre ošetrenie výnimiek
« Odpověď #40 kdy: 23-06-2021, 11:05:37 »
Nejako to už snáď vymyslím. Vychádza mi to tak, žeby som ten druhý kód mal mať vo svojej triede výnimky. Ale čo ďalšie prípadné výnimky?
NE! Vyjimka je v podstate specializovane GO TO vertikalne napric libovolnymi vrstvami kodu, ktere sebou nese nejake hodnoty - parametry a ty mas na urovni jazyka prostredky, jak si stoupnout do cesty a nejak na to zareagovat a nakonec ji obslouzit tj. cestu "vybublavani" vyjimky ukoncit.

A ten druhy kod je to obslouzeni a ukonceni vyjimky, takze typicky bude nekde na urovni top-level akce, napr. v handleru TAction.OnExecute, kde to try-except proste musis napsat v tom handleru.

##

A pokud ji neobslouzis/neukoncis, tak vypadne az na uroven Delphi RTL, coz se projevi vyvolanim udalosti TApplication.OnExecute.

Takze pokud tomu stale nerozumis nebo je ti zatezko to udelat poradne, tak to muzes udelat stylem "Clovece, pos*er se!" a nedelat nic, nechat to vypadnout do teto udalosti a tam zobrazit zpravu "Neco se posr*lo" a v lepsim pripade k tomu jeste pouzit nejake to siditko jako Heureka nebo jak se to vsehno jmenuje, ktera ti nekam do logu zapise stack trace ev. si ho muzes nechat poslat emajlem apod.

Ale IMHO to je tak do nejakych Q&D "strikacek" a ne do solidne napsane aplikace.