Šta koristite u vašim programima kako bi "kulturno" obradili exception-e kod krajnjeg korisnika? Znači poželjno da napravi neki report u kojem je call stack i linija koda gde je bila greška umesto default beskorisnih poruka. MadExcept deluje lepo i profesionalno, ali nije baš jeftin, 100$ a i kupovinom se ne dobijaju buduće verzije. Neki drugi alati koje sam pogledao deluju pomalo neozbiljno i "krhko"...
Exception handling
Zaključano
Zakačeno
Mislim da ne mozes tacno dobiti podatak u kojoj liniji koda je doslo do greske, osim ako ne koristis neki debugger i uradis build sa debug informations.
Ali mozes koristiti Assert tako sto ces postaviti flag [{$ASSERTIONS ON}] u src projekta i onda kada god uradis npr.
dobices exception #227 ako se pozove Assert.
Moze se koristiti i npr.
Exception #227 ces overridovati tako sto ces dodeliti ugradjeni procedure pointer AssertErrorProc na neku svoju proceduru koja je u obliku
Znaci. napises nesto ovako u glavnom fajlu projekta (dpr).
Samo da znas, Line# je broj linije gde je pozvan Assert a ne gde je zaista doslo do greske, ali i to je najcesce sasvim dovoljno da resis problem.
Jos jedna dobra strana ovog metoda je i to sto mozes da logujes svoj tip gresaka ili upozorenja, npr. Assert(False, 'User canceled, exiting silently').
Ali mozes koristiti Assert tako sto ces postaviti flag [{$ASSERTIONS ON}] u src projekta i onda kada god uradis npr.
Code:
try
...
except
Assert(False, 'npr. <record update failed!>')
end;
try
...
except
Assert(False, 'npr. <record update failed!>')
end;
dobices exception #227 ako se pozove Assert.
Moze se koristiti i npr.
Code:
Assert(CopyFile(...), 'CopyFile failed');
//Kopiranje ce se izvrsiti ako je sve ok
//ako nije, tj CopyFile vrati false, izvrsice se assert
Assert(Now < TimeOut, 'Timeout error')
///itd.
Assert(CopyFile(...), 'CopyFile failed');
//Kopiranje ce se izvrsiti ako je sve ok
//ako nije, tj CopyFile vrati false, izvrsice se assert
Assert(Now < TimeOut, 'Timeout error')
///itd.
Exception #227 ces overridovati tako sto ces dodeliti ugradjeni procedure pointer AssertErrorProc na neku svoju proceduru koja je u obliku
Code:
procedure MyEAssertProc(const Message, Filename: string; LineNumber: Integer; ErrorAddr: Pointer);
procedure MyEAssertProc(const Message, Filename: string; LineNumber: Integer; ErrorAddr: Pointer);
Znaci. napises nesto ovako u glavnom fajlu projekta (dpr).
Code:
program ...
uses
SysUtils,
...
{$ASSERTIONS ON}
procedure MyEAssertHandler(const Message, Filename: string; LineNumber: Integer; ErrorAddr: Pointer);
const
DebugFileName = 'C:\Debug.txt';
var
DebugFile: TextFile;
ErrorAddress: String;
begin
AssignFile(DebugFile, DebugFileName);
if FileExists(DebugFileName) then
Append(DebugFile)
else
ReWrite(DebugFile);
ErrorAddress := IntToHex(Integer(ErrorAddr), 0);
WriteLn(DebugFile, '***' + FormatDateTime('dd.MM.yyyy hh:nn', Now) + ' Error at adress ' + ErrorAddress + ' near line #' + IntToStr(LineNumber) + ' in ' + ExtractFileName(FileName) + ': ' + Message);
CloseFile(DebugFile);
end;
begin
Application.Initialize;
AssertErrorProc := @MyEAssertHandler;
...
end.
program ...
uses
SysUtils,
...
{$ASSERTIONS ON}
procedure MyEAssertHandler(const Message, Filename: string; LineNumber: Integer; ErrorAddr: Pointer);
const
DebugFileName = 'C:\Debug.txt';
var
DebugFile: TextFile;
ErrorAddress: String;
begin
AssignFile(DebugFile, DebugFileName);
if FileExists(DebugFileName) then
Append(DebugFile)
else
ReWrite(DebugFile);
ErrorAddress := IntToHex(Integer(ErrorAddr), 0);
WriteLn(DebugFile, '***' + FormatDateTime('dd.MM.yyyy hh:nn', Now) + ' Error at adress ' + ErrorAddress + ' near line #' + IntToStr(LineNumber) + ' in ' + ExtractFileName(FileName) + ': ' + Message);
CloseFile(DebugFile);
end;
begin
Application.Initialize;
AssertErrorProc := @MyEAssertHandler;
...
end.
Samo da znas, Line# je broj linije gde je pozvan Assert a ne gde je zaista doslo do greske, ali i to je najcesce sasvim dovoljno da resis problem.
Jos jedna dobra strana ovog metoda je i to sto mozes da logujes svoj tip gresaka ili upozorenja, npr. Assert(False, 'User canceled, exiting silently').
Naravno da moze da se dobije broj linije i to tacan. Imas u okviru JCL paketa podrsku za to. Ja sam za svoje potrebe napravio mali unit koji mi belezi sve sto je moguce u datoj situaciji. Tu je podatak u kom modulu je doslo do greske, u kojoj linij koda, zatim stack, a moguce je videti i kako je na kraju exception zavrsio. Krajnje korisno i hvata izuzetke bez obzira sto ih mozda u kodu hvatas sa except...end blokom i "ubijas".
Znaci pogledaj:
JclDebug, JclHookExcep unite i mislim da ima i neki primer za koriscenje koji dolazi u z JCL paket.
Znaci pogledaj:
JclDebug, JclHookExcep unite i mislim da ima i neki primer za koriscenje koji dolazi u z JCL paket.
Bolje spreciti nego leciti
izmenjeno 1 put, poslednji put Milos D 30.10.2005. u 16:29
Izmene poruke
- Milos D30.10.2005. u 16:29zapis iz teksta poruke
OK hvala pogledaću JCL.
Naravno, bolje sprečiti nego lečiti. Samo... kada program postane dovoljno velik, koriste se hiljade linija 3rd party koda, a korisnik ima neki egzotičan softver/hardver... tada dobro dodje da korisnik pošalje neki error report sadržajniji od screenshot-a na kome piše access violation - read of address FFFFFFFF...
Naravno, bolje sprečiti nego lečiti. Samo... kada program postane dovoljno velik, koriste se hiljade linija 3rd party koda, a korisnik ima neki egzotičan softver/hardver... tada dobro dodje da korisnik pošalje neki error report sadržajniji od screenshot-a na kome piše access violation - read of address FFFFFFFF...
100 % si u pravu. Ja sam koristio Jedi za neke panele u svojoj aplikaciji i nesto slicno se desilo. To je cena koju sam platio zbog malo sarenila na formi.