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

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

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í):

procedure TForm1.btn1Click(Sender: TObject);
var
  edit: TEdit;
  procedure mTest;
  begin
      edit.Text := 'AV'
  end;
begin
   mTest;
end;

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.

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

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).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

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.

Poslední komentáře

Comment RSS

Dle měsíců