Exception dialog

vložil Radek Červinka 2. srpna 2010 22:28

V každém programu je chyba. A teď co s tím. Podle mne nejhloupější variantou je ukončit program, protože uživatel přijde o data. Můžete pak možná vzývat mrtvolu, ale uživatel to nemusel přežít taky, zvláště pokud program sebou vzal jeho data a on byl slabší na srdce.

Delphi automaticky při chybě - výjimce - program neukončuje, ale zobrazí dialogové okno s informací o chybě a adresou. To je sice lepší z toho pohledu, že uživatel o data nepřijde, ale uživatel nemá např. možnost aplikaci hned ukončit (pokud tedy už jde do tuhého) nebo autora upozornit o chybě.

Standardní dialog

Naštěstí je v Delphi mechanismus, který Vám umožní toto chování změnit.

Máte dvě možnosti jak to udělat, jednoduše nebo složitě. Pokud si vyberete složitou variantu, tak vložte na formulář nevizuální komponentu TApplicationEvents a obslužte událost OnException.

TApplicationEvents

    1procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
    2begin
    3  MessageDlg(E.Message, mtWarning, [mbOK], 0 ) 
    4end;

A co v té obsluze uděláte je Vaše věc.

Mnohem jednodušší je vzít existující obsluhu a upravit si ji k obrazu svému. Jeden takový pěkný dialog je součástí instalace JCL pod licencí MPL a hledejte ho v jcl\experts\debug\dialog\ExceptDlg.pas. No a jen tak pro zajímavost jeho původním autorem je Petr Voneš (podobný, ale velmi vylepšený používá i náš crm systém).

Podle mne nejlepší varianta je si patřičný formulář překopírovat k sobě, upravit dle svého gusta a začlenit do svého projektu (nejlépe v dpr). Formulář se v inicializační sekci sám napojí na dříve uvedenou událost.

Nyní je na čase vytvořit nějaký cool testovací projekt, který bude padat jako hruška. Třeba něco podobného jako následující kód obsluhující tlačítko (proč je tam procedura mTest pochopíte vzápětí):

    1procedure TForm1.btn1Click(Sender: TObject);
    2var
    3  edit: TEdit;
    4  procedure mTest;
    5  begin
    6      edit.Text := 'AV'
    7  end;
    8begin
    9   mTest;
   10end;

Po spuštění a kliknutí na tlačítko se objeví následující (na obrázku už rozbalený) dialog (ten si samozřejmě můžete upravit)

Exception dialog

Teď záleží, jak máte nastavený linker, tj. jak moc informací se dalo z EXE a spol. zjistit. V minimální variantě dostanete něco takového:

Exception class: EAccessViolation
Exception message: Access violation at address 00484141 in module 'Project1.exe'. 
Read of address 0000003E.
Exception address: 00484141
------------------------------------------------------------------------------
Stack list, generated 2.8.2010 21:04:05
(00083141){Proj1.exe} [00484141]
(00081BA9){Proj1.exe} [00482BA9]
(00081C39){Proj1.exe} [00482C39]
(00081C86){Proj1.exe} [00482C86]
(00081CB8){Proj1.exe} [00482CB8]
(000EF962){Proj1.exe} [004F0962]
(000EF985){Proj1.exe} [004F0985]
(00083A8B){Proj1.exe} [00484A8B]
(000639B6){Proj1.exe} [004649B6]
(00064474){Proj1.exe} [00465474]

Což Vám moc nepomůže, ale pokud byl při překladu generován map soubor (Project / Option / Linking /Map file - detailed), lze pomocí jiného programu výpis zásobníku volání (stack trace) rekonstruovat. Program je jcl\bin\ExceptionReportConverter.exe, a jeho zdrojové kódy se dají najít v instalaci JCL (ale není to nutné).

Exception dialog Vám soubor logu vygeneruje při chybě, popř. si ho můžete nechat poslat. Tento soubor, spolu s map souborem předhodíte programu a ten se Vám odvděčí rekonstrukcí volání.

Exception dialog

Výsledek pak vypadá nějak takto (pokud byl map soubor korektní):

Exception class: EAccessViolation
Exception message: Access violation at address 00484141 in module 'Project1.exe'. Read of address 0000003E.
Exception address: 00484141
------------------------------------------------------------------------------
Stack list, generated 2.8.2010 21:04:05
(00083141){Proj1.exe} [00484141] Controls.Controls.TControl.Perform + $21
(00081BA9){Proj1.exe} [00482BA9] Controls.Controls.TControl.GetTextLen + $9
(00081C39){Proj1.exe} [00482C39] Controls.Controls.TControl.GetText + $9
(00081C86){Proj1.exe} [00482C86] Controls.Controls.TControl.SetText + $1E
(00081CB8){Proj1.exe} [00482CB8] Controls.Controls.TControl.SetText + $50
(000EF962){Proj1.exe} [004F0962] Unit1.Unit1.mTest (Line 31, "Unit1.pas" + 1) + $B
(000EF985){Proj1.exe} [004F0985] Unit1.Unit1.TForm1.btn1Click (Line 34, "Unit1.pas" + 1) + $1
(00083A8B){Proj1.exe} [00484A8B] Controls.Controls.TControl.Click + $6F
(000639B6){Proj1.exe} [004649B6] StdCtrls.StdCtrls.TCustomButton.Click + $1E
(00064474){Proj1.exe} [00465474] StdCtrls.StdCtrls.TCustomButton.CMDialogKey + $50
(00083520){Proj1.exe} [00484520] Controls.Controls.TControl.WndProc + $2D4
(00087DE8){Proj1.exe} [00488DE8] Controls.Controls.TWinControl.WndProc + $568

Z tohoto logu už lze celkem vypozorovat co se tak mohlo stát. Jen upozorním, že místo chyby je úplně nahoře a náš kód je na 5 řádku.

Kromě možnosti s map souborem, lze použít i možnost vložení JDBG přímo do aplikace. Tuto možnost nabízí standardně instalovaný expert z JCL do Delphi v menu Project úplně dole. JDBG jsou komprimované informace generované z map souboru, které jsou vloženy přímo do EXE.

Pokud tuto možnost použijete, nepotřebujete map soubor, ale výsledné exe bude o krapet větší a uživatel Vám uvidí stack trace. Co Vám bude vyhovovat je už na Vás. Nebo můžete použít i jiné komponenty, třeba velmi propracovaný eurekalog.


Nabízíme Delphi školení a konzultace na různá témata, primárně ve Vaší firmě.

Tagy: , ,

Praxe

Komentáře

18.3.2014 14:11:01 #

TLama

Z hotových řešení bych doporučil madExcept:

http://madshi.net/madExceptDescription.htm

TLama

Komentování ukončeno

Naše nabídka

Partial English version.

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy nebo burzy práce).

Pokud chcete podpořit tento server libovolnou částkou, můžete použít PayPal. Moc děkuji.

Delphi Certified Developer

O Delphi.cz

Delphi je jediný moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64 , Mac OSX a na iPhone a Android (s výhledem na další platformy díky FireMonkey) na současném trhu (včetně Windows 8.1).

V současnosti je světová komunita přes dva miliónů vývojářů.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Anketa

Poslední komentáře

Comment RSS