henryreynolds
asked on
Handling exceptions ( hide exception from users create log file of exception)
Good day
I am running a end of day process at a hotel every night, my problem is that my program return error messages when a error occurred and then I get a phone call late at night.
Typical error messages are the following.
1.I create a pdf file of the report and then I copy it to a server, sometimes a error occur when the file gets copied and the the user see the delphi exception and phone me.
2.Sometimes the sql returns a error message ( this shoudnt actualy happen but it is my fault and I need to fix the bugs)
What can I do when a exception occur, to completely hide or avoid Delphi to show the message and rather in the background create a log file and then send the log file to me by e-mail.
This will help me not to worry every night, and the users wont have to deak with error messages.
Thank you
I am running a end of day process at a hotel every night, my problem is that my program return error messages when a error occurred and then I get a phone call late at night.
Typical error messages are the following.
1.I create a pdf file of the report and then I copy it to a server, sometimes a error occur when the file gets copied and the the user see the delphi exception and phone me.
2.Sometimes the sql returns a error message ( this shoudnt actualy happen but it is my fault and I need to fix the bugs)
What can I do when a exception occur, to completely hide or avoid Delphi to show the message and rather in the background create a log file and then send the log file to me by e-mail.
This will help me not to worry every night, and the users wont have to deak with error messages.
Thank you
www.eurekalog.com
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
the unit uLogging
unit uLogging;
interface
procedure AddLog(Msg: string; DateTimeLinePrefix: boolean = True; LogPrefix: string = '');
implementation
uses Classes, SysUtils, SyncObjs;
var cs: TCriticalSection;
procedure AddToLog(LOG_PATH: string; LOG_MAXSIZE: integer; LOG_LIFETIME: double;
Msg: string; LogPrefix: string = ''; DateTimeLinePrefix: Boolean = True);
var
sr: TSearchRec;
LogFile: TextFile;
ValidFile, SearchPath: string;
valid: boolean;
j: integer;
TimeStr : string;
begin
cs.Enter;
try
SearchPath := IncludeTrailingPathDelimiter(Trim(LOG_PATH));
if not DirectoryExists(SearchPath) then
ForceDirectories(SearchPath);
ValidFile := '';
if FindFirst(format('%s%s*.log', [SearchPath, LogPrefix]), faAnyFile, sr) = 0 then
try
repeat
if sr.Size < LOG_MAXSIZE * 1024 then
ValidFile := sr.Name
else
if FileDateToDateTime(sr.Time) < Now - LOG_LIFETIME then
DeleteFile(Pchar(SearchPath + sr.Name));
until FindNext(sr) <> 0;
finally
FindClose(sr);
end;
try
if ValidFile <> '' then
begin
j := 0;
repeat
try
AssignFile(LogFile,format('%s%s',[SearchPath, ValidFile]));
Append(LogFile);
valid := true;
except
Inc(j);
valid := false;
sleep(500);
end;
until valid or (j > 2);
end
else
begin
j := 0;
repeat
try
Rewrite(Logfile, Format('%s%s_%s.log', [SearchPath, LogPrefix, FormatDateTime('ddmmhhnn',now)]));
valid := true;
except
Inc(j);
valid := false;
sleep(500);
end;
until valid or (j > 2);
end;
j := 0;
repeat
try
if DateTimeLinePrefix then
begin
DateTimeToString(TimeStr, 'DD/MM/YYYY HH:NN:SS', Now);
Msg := TimeStr + ' - ' + Msg;
end;
Writeln(LogFile, Msg);
valid := true;
except
Inc(j);
valid := false;
sleep(500);
end;
until valid or (j > 2);
finally
CloseFile(LogFile);
end;
finally
cs.Leave;
end;
end;
procedure AddLog(Msg: string; DateTimeLinePrefix: boolean = True; LogPrefix: string = '');
begin
// Keep messages 1 day and max log file size = 20K
AddToLog(ExtractFilePath(ParamStr(0)), 20, 1, Msg, LogPrefix, DateTimeLinePrefix);
end;
initialization
cs := TCriticalSection.Create;
finalization
cs.Free;
end.
I don't have that much experience with madshi, so I don't know if it can do what henryreynolds asked :)
the above samples create 2 files, the daytime log and the nighttime log
if you use madshi or eurekalog then all you need to is set the options in the app to send the mails
question:
do you really check your mails at night ?
and if not, do you really have to send them ?
if so, then you could still implement following to send the log files:
https://www.experts-exchange.com/questions/10032527/Sending-Mail-Attachments-in-Delphi.html
or
https://www.experts-exchange.com/questions/21152145/How-to-send-a-mail-with-an-attachment-with-outlook-from-Delphi-7.html
if you use madshi or eurekalog then all you need to is set the options in the app to send the mails
question:
do you really check your mails at night ?
and if not, do you really have to send them ?
if so, then you could still implement following to send the log files:
https://www.experts-exchange.com/questions/10032527/Sending-Mail-Attachments-in-Delphi.html
or
https://www.experts-exchange.com/questions/21152145/How-to-send-a-mail-with-an-attachment-with-outlook-from-Delphi-7.html
Not sure if I understand Geert_Gruwez: eurekalog has everything you need included: hiding, logging, and mailing to you (optionally including screen shot, etc).
madshi has all that too.
I just showed how it can be done without 3rd part software
I just showed how it can be done without 3rd part software
ASKER
Hi
Sorry for getting back to all now, I dont care much about the e-mails, the most important for me is to hide the error message and just create a log of the error.
Here is a sample of my code, at this stage I am using a try and except.
How can I implement it in the except part.
This sample a create a pdf file using fast report and copy the file to a server, sometimes the server has a problem and then I get a error message.
Sorry for getting back to all now, I dont care much about the e-mails, the most important for me is to hide the error message and just create a log of the error.
Here is a sample of my code, at this stage I am using a try and except.
How can I implement it in the except part.
This sample a create a pdf file using fast report and copy the file to a server, sometimes the server has a problem and then I get a error message.
try
dmReport.frxPDFExport.ShowDialog := False;
dmReport.frxPDFExport.ShowProgress := false;
exportFileName := ExportFileName+'\Night Audit Statements For '+FormatDateTime('dd-mm-yyyy',dm.sTradingDate)+'.pdf';
dmReport.frxPDFExport.FileName := trim(ExportFileName);
dmReport.frxReport.Export(dmReport.frxPDFExport);
memLog.Lines.Add('Export Report Successful');
except
memLog.Lines.Add('Export Report FAILED');
end;
you don't need to catch the exceptions all over
the solutions provided catches *ALL UNHANDLED* exceptions and logs them to file
the application has a event handler to catch all these exceptions:
Application.OnException
the solutions provided catches *ALL UNHANDLED* exceptions and logs them to file
the application has a event handler to catch all these exceptions:
Application.OnException
ASKER
Hi Geert
Thank you very much, but will this also catch a sql error for example
Must I always use try and in the except and in the except part call the Raise exception
Thank you very much, but will this also catch a sql error for example
Must I always use try and in the except and in the except part call the Raise exception
with qryData do
begin
close;
sql.clear.
sql.add('select * from table_does_not_exists');
try
execute;
except
Raise Exception.Create('TABLE DOES NOT EXISTS.....');
end
end;
yup no exctinctions are made
i was gonna say exceptions first ...
ASKER
Hi Geert
Then I am sure this will solve my problem, because this was a very big headache for me.
I spoke to the guy who is in charged of the network and server at the hotel now, and he said to me he checked the windows log file, and windows did a update last night and automatically restarted the server.
I really dont know what to do to prevent errors such as last night, because the night audit that the hotel run can take some times +- 30min, when the printing is done then all the exporting happens and I commit all the transaction. What is a safe method to make sure the server does not go offline, or must I just test before exporting that the server is still online.
Then I am sure this will solve my problem, because this was a very big headache for me.
I spoke to the guy who is in charged of the network and server at the hotel now, and he said to me he checked the windows log file, and windows did a update last night and automatically restarted the server.
I really dont know what to do to prevent errors such as last night, because the night audit that the hotel run can take some times +- 30min, when the printing is done then all the exporting happens and I commit all the transaction. What is a safe method to make sure the server does not go offline, or must I just test before exporting that the server is still online.
server restarted ?
your application server ?
or your database server ?
or your print server ?
or both ?
your application server ?
or your database server ?
or your print server ?
or both ?
ASKER
Hi Geert
Here is a screen shot of the log of windows, I still cant believe windows will restart especially a server
restart.JPG
Here is a screen shot of the log of windows, I still cant believe windows will restart especially a server
restart.JPG
ASKER
No I am worried how I can protect my application and database, especially when there are open transaction like last night and windows are restarting.
And how must I handle such cases, because when the night audit start running I update a field in the database to say that the night audit is currently running, I use this to prevent users to log on and process documents.
But I think with this method of yours I will bring up a message and tell the user to restart the night audit process
And how must I handle such cases, because when the night audit start running I update a field in the database to say that the night audit is currently running, I use this to prevent users to log on and process documents.
But I think with this method of yours I will bring up a message and tell the user to restart the night audit process
what database are you using ?
night audit ???
what would you be doing then ?
what would you be doing then ?
ASKER
Firebird 2
Night Audit, the process that create accommodation charges and print all the reports and move the date on to the next day
Night Audit, the process that create accommodation charges and print all the reports and move the date on to the next day
@Geert,
I don't agree with your statement that ou don't need to handle exceptions "all over". If you have one universal exception handler, then it is, IMHO, considerably more difficult to determine what went wrong and where. My preference is for wrapping the various potential exceptions (or, at the very least, the code in a procedure of function) in a TRY . . . EXCEPT and I quite frequently Wrap them in TRY TRY . . . EXCEPT . . . END FINALLY so that I can make sure that things get cleaned up even if there is an exception thrown.
Admittedly, I often have a universal exception handler for those exceptions that float that far out. However, relying only on that for handling all of your exceptions i, again IMHO, an unsound approach to coding in Delphi.
I don't agree with your statement that ou don't need to handle exceptions "all over". If you have one universal exception handler, then it is, IMHO, considerably more difficult to determine what went wrong and where. My preference is for wrapping the various potential exceptions (or, at the very least, the code in a procedure of function) in a TRY . . . EXCEPT and I quite frequently Wrap them in TRY TRY . . . EXCEPT . . . END FINALLY so that I can make sure that things get cleaned up even if there is an exception thrown.
Admittedly, I often have a universal exception handler for those exceptions that float that far out. However, relying only on that for handling all of your exceptions i, again IMHO, an unsound approach to coding in Delphi.
ASKER
@ Geert
Maybe Diver has a point, is it possible to use this method on the night audit routine only or what do you suggest
Maybe Diver has a point, is it possible to use this method on the night audit routine only or what do you suggest
>>8080_Diver
this is just for unhandled exceptions
if you want to handle exceptions while your audit is run (see snippet)
this will create files like "auditxxxxx.log"
this is just for unhandled exceptions
if you want to handle exceptions while your audit is run (see snippet)
this will create files like "auditxxxxx.log"
uses uLogging;
try
except
on E: exception do
AddLog(E.Message, True, 'audit');
end;
@Geert,
you don't need to catch the exceptions all over
That was what I was responding to. ;-)
@all,
By the way, I have a small unit that I created (about 8 years ago now) that I am willing to provide for free to anyone who is interested. It allows you to write to one or more log files from a Delphi app (although, all of the log files will have the same name as the App while having different "types, e.g. ".log", ".err"). It also has provisions for indenting and unindenting (outdenting?). It will date and time stamp each entry in the log and can date stamp the loag file name (e.g. "appname_20090911.log").
If nothing else, the price is right. ;-)
you don't need to catch the exceptions all over
That was what I was responding to. ;-)
@all,
By the way, I have a small unit that I created (about 8 years ago now) that I am willing to provide for free to anyone who is interested. It allows you to write to one or more log files from a Delphi app (although, all of the log files will have the same name as the App while having different "types, e.g. ".log", ".err"). It also has provisions for indenting and unindenting (outdenting?). It will date and time stamp each entry in the log and can date stamp the loag file name (e.g. "appname_20090911.log").
If nothing else, the price is right. ;-)
>>8080_Diver
you may look at my earlier posts in this Q ...
you may look at my earlier posts in this Q ...
ASKER
-> geert
I am not 100% with you , what must I do to ignore your exception method and allow for normal exception handling in other modules.
I am not 100% with you , what must I do to ignore your exception method and allow for normal exception handling in other modules.
In order to handle the exceptions in the rest of your code, you need to wrap code segments in TRY . . . EXCEPT . . . END blocks. In the Except portion, you need to capture the exception, determine (during the creation of the code) what you can and cannot handle locally, how you will handle things locally, and whether you will reraise the exception for the next outer level. As I mention above, I usually include TRY . . . FINALLY . . . END code so that I can make sure that things like database connections or transactions are handled and closed (or rolledback) gracefully.
try
try
MyAdoConnection.Connect;
.
.
try
MyAdoQuery.Open;
{do some work}
except
on E:Exception do
begin
if {exception can be handled}
then begin
{handle the exception}
end
else begin
{do whatever set up is required}
raise Excpetion.Create('meaningful text for humans;' +
#13#10 + E.Message);
end; {if}
end; {on exception}
end; {try}
finally
{do any necessary housekeeping}
if (MyAdoConnection.Connected)
then begin
MyAdoConnection.Close;
end; {if}
end; {try}
elaborating further from your example
with qryData do
begin
close;
sql.clear.
sql.add('select * from table_does_not_exists');
try
execute;
except
on E: Exception do
AddLog('TABLE DOES NOT EXISTS. (' + E.Message + ')', True, 'audit');
end
end;
ASKER
-> geert
I have worked with your smple code last night in my application, and it will work, but is it possible that I only use the exception method in my one unit, this will mean when the user enter that form I activates
Application.OnException := CatchException;
and when the user is finished in that unit I restore Application.OnException := " to default", this mean in all other units delphi will raise exceptions as normal.
what I ment from my example is , normally my exception come from sql sometimes I forget to assign privelages to all users or I forgot to compile a new procedure and delphi cant find that procedure.
I all my units except the one unit that runs the night audit, delphi my riase the normal exception, but in my night audit unit the exception must be catch by your method.
* i am increasing the points, because I think you and diver spend a lot of valuable time on my problem thank you.
I have worked with your smple code last night in my application, and it will work, but is it possible that I only use the exception method in my one unit, this will mean when the user enter that form I activates
Application.OnException := CatchException;
and when the user is finished in that unit I restore Application.OnException := " to default", this mean in all other units delphi will raise exceptions as normal.
what I ment from my example is , normally my exception come from sql sometimes I forget to assign privelages to all users or I forgot to compile a new procedure and delphi cant find that procedure.
I all my units except the one unit that runs the night audit, delphi my riase the normal exception, but in my night audit unit the exception must be catch by your method.
* i am increasing the points, because I think you and diver spend a lot of valuable time on my problem thank you.
with qryData do
begin
close;
sql.clear.
sql.add('select * from table_does_not_exists');
try
execute;
except
Raise Exception.Create('TABLE DOES NOT EXISTS.....');
end
end;
ASKER
increasing points because of valueble help and I need to understand more to solve m y problem and other exceptions problems thanx @geert and @diver
if you only want to catch it in 1 unit
you don't use Application.OnException
you use :
try
problemcode
except
on E: Exception do
AddLog('procedure X caused : ' + E.Message, True, 'audit');
end;
if you want different logs for other units just change 'audit' into something else
the line on E: Exception allways for further investigating of the error
as i read your code, it seems there are some major problems in your program
because of windows updates and server reboot
the one thing strikes me as odd:
the windows patches are automatically deployed on the server and automatically rebooted
i would strongly advise against this
they should be controlled and the reboot should be done in a controlled way
we do monthly reboots too because of the windows updates
we have the problem of working in a highly automated production facility
this means we have to warn production they will have no data for 30minutes while rebooting
obviously somebody has failed to see the significance of communicating with you about this rebooting
and patching
you should work out a policy with them so you know when the server is going down
it would save you a lot of headache
otherwise you would have to program n-tier where the application server buffers while the database is down
off course, you would be screwed if they bring down the app and db server at the same time
which looking at things they would do without a single thought as to why not
you don't use Application.OnException
you use :
try
problemcode
except
on E: Exception do
AddLog('procedure X caused : ' + E.Message, True, 'audit');
end;
if you want different logs for other units just change 'audit' into something else
the line on E: Exception allways for further investigating of the error
as i read your code, it seems there are some major problems in your program
because of windows updates and server reboot
the one thing strikes me as odd:
the windows patches are automatically deployed on the server and automatically rebooted
i would strongly advise against this
they should be controlled and the reboot should be done in a controlled way
we do monthly reboots too because of the windows updates
we have the problem of working in a highly automated production facility
this means we have to warn production they will have no data for 30minutes while rebooting
obviously somebody has failed to see the significance of communicating with you about this rebooting
and patching
you should work out a policy with them so you know when the server is going down
it would save you a lot of headache
otherwise you would have to program n-tier where the application server buffers while the database is down
off course, you would be screwed if they bring down the app and db server at the same time
which looking at things they would do without a single thought as to why not
I forget to assign privelages to all users or ...
i dunno about firebird, but i use roles in the database
you assign all priviliges to a role (or more roles) and assign the roles to the user
make such a user for yourself and then test with that
should let you forget less priviliges
for the other parts ... google for dunit testing
i dunno about firebird, but i use roles in the database
you assign all priviliges to a role (or more roles) and assign the roles to the user
make such a user for yourself and then test with that
should let you forget less priviliges
for the other parts ... google for dunit testing
ASKER
-- geert
If my application has two forms, I want on the one form normal exceptions by delphi and on the other form I want exceptions been ignored (I want to use your code ).
How can I implement this ?
I have include a sample app, I don't think you will be able to run it because I have components from devart on my form, but this will give you a idea.
Regards
Henry
If my application has two forms, I want on the one form normal exceptions by delphi and on the other form I want exceptions been ignored (I want to use your code ).
How can I implement this ?
I have include a sample app, I don't think you will be able to run it because I have components from devart on my form, but this will give you a idea.
Regards
Henry
unit formUseDelphiException;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IBC, DB, MemDS, DBAccess;
type
TfrmUseDelphiException = class(TForm)
Button1: TButton;
IBCConnection1: TIBCConnection;
dsData: TIBCDataSource;
qryData: TIBCQuery;
IBCTransaction1: TIBCTransaction;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmUseDelphiException: TfrmUseDelphiException;
implementation
uses
formIgnoreDelphi;
{$R *.dfm}
/////////////////////// THIS form must use delphi exception /////////////////////////////
procedure TfrmUseDelphiException.Button1Click(Sender: TObject);
var
sQryResult : string;
begin
with qryData do
begin
close;
sql.Clear;
sQryResult := Format('Select oooo from holders',
[]) ;
sql.Add(sQryResult);
prepare;
try
execute;
except
end;
end;
end;
procedure TfrmUseDelphiException.Button2Click(Sender: TObject);
begin
Application.CreateForm(TfrmIgnoreDelphi, frmIgnoreDelphi);
try
frmIgnoreDelphi.ShowModal();
finally
frmIgnoreDelphi.Free;
end;
end;
end.
//this form must ignore delphi exceptions and log it
unit formIgnoreDelphi;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, MemDS, DBAccess, IBC, StdCtrls;
type
TfrmIgnoreDelphi = class(TForm)
Button1: TButton;
dsData: TIBCDataSource;
qryData: TIBCQuery;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure CatchException(Sender: TObject; E: Exception);
procedure AddErrorLog(aMessage: string);
public
{ Public declarations }
end;
var
frmIgnoreDelphi: TfrmIgnoreDelphi;
implementation
uses
uLogging;
{$R *.dfm}
procedure TfrmIgnoreDelphi.AddErrorLog(aMessage: string);
var logPrefix: string;
begin
logPrefix := 'daytime';
if (Frac(Now) > 1/24*18) or (Frac(Now) < 1/24*7) then
logPrefix := 'nighttime';
AddLog(aMessage, True, logprefix);
end;
procedure TfrmIgnoreDelphi.CatchException(Sender: TObject; E: Exception);
begin
AddErrorLog(E.Message);
end;
procedure TfrmIgnoreDelphi.FormCreate(Sender: TObject);
begin
Application.OnException := CatchException;
end;
procedure TfrmIgnoreDelphi.Button1Click(Sender: TObject);
begin
with qryData do
begin
close;
sql.Clear;
sql.Add('select Koos from Holders');
try
execute;
except
on E: exception do
Raise Exception.Create('Hey, you got an exception !');
end;
end;
end;
end.
if you want to log specific exceptions for a specific task to a specific file
then ... you guessed it ... you'll have to get specific
and ... application.onException is not specific
using your code sample:
then ... you guessed it ... you'll have to get specific
and ... application.onException is not specific
using your code sample:
unit formUseDelphiException;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IBC, DB, MemDS, DBAccess;
type
TfrmUseDelphiException = class(TForm)
Button1: TButton;
IBCConnection1: TIBCConnection;
dsData: TIBCDataSource;
qryData: TIBCQuery;
IBCTransaction1: TIBCTransaction;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmUseDelphiException: TfrmUseDelphiException;
implementation
uses
formIgnoreDelphi;
{$R *.dfm}
/////////////////////// THIS form must use delphi exception /////////////////////////////
procedure TfrmUseDelphiException.Button1Click(Sender: TObject);
var
sQryResult : string;
begin
with qryData do
begin
close;
sql.Clear;
sQryResult := Format('Select oooo from holders',
[]) ;
sql.Add(sQryResult);
prepare;
try
execute;
except
// um ... you are throwing away the exceptions here
// or is this what you wanted ?
end;
end;
end;
procedure TfrmUseDelphiException.Button2Click(Sender: TObject);
begin
Application.CreateForm(TfrmIgnoreDelphi, frmIgnoreDelphi);
try
frmIgnoreDelphi.ShowModal();
finally
frmIgnoreDelphi.Free;
end;
end;
end.
//this form must ignore delphi exceptions and log it
unit formIgnoreDelphi;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, MemDS, DBAccess, IBC, StdCtrls;
type
TfrmIgnoreDelphi = class(TForm)
Button1: TButton;
dsData: TIBCDataSource;
qryData: TIBCQuery;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure AddErrorLog(aMessage: string);
public
{ Public declarations }
end;
var
frmIgnoreDelphi: TfrmIgnoreDelphi;
implementation
uses
uLogging;
{$R *.dfm}
procedure TfrmIgnoreDelphi.AddErrorLog(aMessage: string);
begin
AddLog(aMessage, True, 'audit');
end;
procedure TfrmIgnoreDelphi.Button1Click(Sender: TObject);
begin
with qryData do
begin
close;
sql.Clear;
sql.Add('select Koos from Holders');
try
execute;
except
on E: exception do
AddErrorLog('Hey, you got an exception :' + E.Message);
end;
end;
end;
end.
ASKER
--Geert
the form "formUseDelphiException" must use the normal Application exception, it must not use the addlog method.
Because I want my application to throw exception it there is maybe errors in my code, and I dont know anout it.
try
execute;
except
//the application must raise a exception on its own if there was a problem e.g maybe I have call my procedure incorrect
end
the form "formUseDelphiException" must use the normal Application exception, it must not use the addlog method.
Because I want my application to throw exception it there is maybe errors in my code, and I dont know anout it.
try
execute;
except
//the application must raise a exception on its own if there was a problem e.g maybe I have call my procedure incorrect
end
this will throw away your exception
try
execute;
except
end
if you want a exception, then don't put any try except around it
or at least reraise it
try
execute;
except
on E: Exception do
begin
AddLog(E.Message); // if you want to log it
Raise; // this raises the same exceptions again
end;
end;
try
execute;
except
end
if you want a exception, then don't put any try except around it
or at least reraise it
try
execute;
except
on E: Exception do
begin
AddLog(E.Message); // if you want to log it
Raise; // this raises the same exceptions again
end;
end;
ASKER
Geert sorry to be so stupid now, if I understand you correctly the following code wont raise a exception
try
execute;
except // is it because there is nothing in the except part ???
end
but this will raise a exception
try
execute;
except
ShowMessage('ERROR IN APP');
end
You see my problem is, places where I call sql statements I do the following
with qryData do
begin
close;
sql.clear;
sql.add('select * from ..... ');
execute;
end;
* i dont use try and except, I think this is very wrong of me or what ?
there are different ways of raising and handling exceptions:
following code:
try
execute;
except // is it because there is nothing in the except part ???
end
explanation:
yup, all exceptions are deleted because the except end is empty
following code:
but this will raise a exception
try
execute;
except
ShowMessage('ERROR IN APP');
end
explanation:
this raises an exception, you catch it, and you don't care which it is
you show a message to the user 'ERROR IN APP'
following code:
with qryData do
begin
close;
sql.clear;
sql.add('select * from ..... ');
execute;
end;
explanation:
the system will raise a exception on the execute
if you have not altered the default exception handler (Application.OnException) then a message is show to the user with exception.Message
otherwise your handler is used and you do what you want with it in there
you need to clearly make out the following in each piece of code:
1: do i catch any exceptions ?
2: do i log the exceptions ?
3: do i show a message to the user ?
4: do i reraise the exception ?
5: do i need to provide a overal exception handler to catch this exception ?
5 could be the eurekalog or madshi option
you seem not to be aware of the different ways of catching a exception.
the delphi help (at least the version 7) is a good place to start reading on this
read chapter 14 of this book:
http://veerle-en-geert.be/delphi/ebooks/Delphi%20-%20Teach%20Yourself%20Borland%20Delphi%204%20in%2021%20Days.pdf
following code:
try
execute;
except // is it because there is nothing in the except part ???
end
explanation:
yup, all exceptions are deleted because the except end is empty
following code:
but this will raise a exception
try
execute;
except
ShowMessage('ERROR IN APP');
end
explanation:
this raises an exception, you catch it, and you don't care which it is
you show a message to the user 'ERROR IN APP'
following code:
with qryData do
begin
close;
sql.clear;
sql.add('select * from ..... ');
execute;
end;
explanation:
the system will raise a exception on the execute
if you have not altered the default exception handler (Application.OnException) then a message is show to the user with exception.Message
otherwise your handler is used and you do what you want with it in there
you need to clearly make out the following in each piece of code:
1: do i catch any exceptions ?
2: do i log the exceptions ?
3: do i show a message to the user ?
4: do i reraise the exception ?
5: do i need to provide a overal exception handler to catch this exception ?
5 could be the eurekalog or madshi option
you seem not to be aware of the different ways of catching a exception.
the delphi help (at least the version 7) is a good place to start reading on this
read chapter 14 of this book:
http://veerle-en-geert.be/delphi/ebooks/Delphi%20-%20Teach%20Yourself%20Borland%20Delphi%204%20in%2021%20Days.pdf
* i dont use try and except, I think this is very wrong of me or what ?
that depends on what the code does
that depends on what the code does
ASKER
I refer to the following statement
following code:
with qryData do
begin
close;
sql.clear;
sql.add('select * from ..... ');
execute;
end;
explanation:
************************** ********** ********** ********** ********** ********** ********** *******
the system will raise a exception on the execute
*if you have not altered the default exception handler (Application.OnException) then a message is show to the user with exception.Message
otherwise your handler is used and you do what you want with it in there
** If I have altered the default exception handler, how do I set it back to the default handler.
following code:
with qryData do
begin
close;
sql.clear;
sql.add('select * from ..... ');
execute;
end;
explanation:
**************************
the system will raise a exception on the execute
*if you have not altered the default exception handler (Application.OnException) then a message is show to the user with exception.Message
otherwise your handler is used and you do what you want with it in there
** If I have altered the default exception handler, how do I set it back to the default handler.
well the default handler for onexception = nil
this is how the application object handles exceptions
procedure TApplication.HandleExcepti on(Sender: TObject);
begin
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
if ExceptObject is Exception then
begin
if not (ExceptObject is EAbort) then
if Assigned(FOnException) then
FOnException(Sender, Exception(ExceptObject))
else
ShowException(Exception(Ex ceptObject ));
end else
SysUtils.ShowException(Exc eptObject, ExceptAddr);
end;
so if you want to set it back to the default:
Application.OnException := nil;
basically the default handler comes down to
try
except
on E: Exception do
Application.ShowException( E);
end;
this is how the application object handles exceptions
procedure TApplication.HandleExcepti
begin
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
if ExceptObject is Exception then
begin
if not (ExceptObject is EAbort) then
if Assigned(FOnException) then
FOnException(Sender, Exception(ExceptObject))
else
ShowException(Exception(Ex
end else
SysUtils.ShowException(Exc
end;
so if you want to set it back to the default:
Application.OnException := nil;
basically the default handler comes down to
try
except
on E: Exception do
Application.ShowException(
end;
or if you want to be absolutely sure:
type
TfrmIgnoreDelphi = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
fSaveExceptionHandler: TExceptionEvent;
procedure CatchException(Sender: TObject; E: Exception);
end;
var
frmIgnoreDelphi: TfrmIgnoreDelphi;
procedure TfrmIgnoreDelphi.CatchException(Sender: TObject; E: Exception);
begin
AddErrorLog(E.Message);
end;
procedure TfrmIgnoreDelphi.FormCreate(Sender: TObject);
begin
fSaveExceptionHandler := Application.OnException;
Application.OnException := CatchException;
end;
procedure TfrmIgnoreDelphi.FormDestroy(Sender: TObject);
begin
Application.OnException := fSaveExceptionHandler;
end;
ASKER
-- Hi Geert
I think I am finished with you now, thank you very , very much. I am not closing the question now, because I think it is fare that you should earn all 500 points, but I must just think about it for a second or two.
Thank you very much
Henry
I think I am finished with you now, thank you very , very much. I am not closing the question now, because I think it is fare that you should earn all 500 points, but I must just think about it for a second or two.
Thank you very much
Henry
if need be, you can allways open more questions ...
in a second or two.
in a second or two.