Recent

Author Topic: how to find out what exceptions might get raised  (Read 4072 times)

rgh

  • New Member
  • *
  • Posts: 49
how to find out what exceptions might get raised
« on: June 03, 2017, 03:50:00 pm »
As an example, this code that attempts to connect to a database.
Code: Pascal  [Select][+][-]
  1. Program ConnectPG;
  2.  
  3. uses
  4.   pqconnection, sysutils;
  5.  
  6. function CreateConnection: TPQConnection;
  7. begin
  8.   result := TPQConnection.Create(nil);
  9.   result.Hostname := '10.1.0.1';
  10.   result.Params.Add('port=5432');            
  11.   result.DatabaseName := 'test';
  12.   result.UserName := 'user1';
  13.   result.Password := 'wrong-password';
  14. end;
  15.  
  16. var  
  17.   AConnection : TPQConnection;
  18.  
  19. begin
  20.   AConnection := CreateConnection;
  21.   try
  22.     AConnection.Open;
  23.     if Aconnection.Connected then
  24.       writeln('connected ok!');
  25.     AConnection.Close;
  26.   except
  27.     on e: Exception do
  28.       writeln(e.ToString);
  29.   end;
  30.   FreeAndNil(AConnection);
  31. end.

The attempt fails on account of the password being wrong, an EDatabaseError being raised.

Drilling into the ancestry of  TPQConnection, the Open method is defined in TCustomConnection and looking up that class

https://www.freepascal.org/docs-html/fcl/db/tcustomconnection.open.html


as far as I can see, doesn't tell me what exceptions might get thrown. What's the pascal way of knowing what exception classes I might need to deal with?



sky_khan

  • Guest
Re: how to find out what exceptions might get raised
« Reply #1 on: June 03, 2017, 04:11:13 pm »
Sorry, if you mean something like java's, there is none. Documentation may or may not help. Only way to be sure is mastering the code you deal with.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: how to find out what exceptions might get raised
« Reply #2 on: June 03, 2017, 06:28:34 pm »
What's the pascal way of knowing what exception classes I might need to deal with?
If you can guess the possibilities, test with is operator. Otherwise, you can use the ClassName property to log or display it.

rgh

  • New Member
  • *
  • Posts: 49
Re: how to find out what exceptions might get raised
« Reply #3 on: June 03, 2017, 10:07:00 pm »
Thanks for the clarification guys.

Understanding the source of all the classes I use, seems like a overwhelming task, if I'm understanding SkyKan correctly. So, if I don't already know, somehow, what exceptions can get raised, I'm left with trying to discover them during testing and hope that I anticipate all the bad stuff that can happen.

Doesn't seem satisfactory.

Exception handling is an area where, I think, java's catch or declare requirement is better than what's currently available in object pascal.


sky_khan

  • Guest
Re: how to find out what exceptions might get raised
« Reply #4 on: June 03, 2017, 11:18:11 pm »
I'm not experienced in Java but the thing is, most of the time you cant recover from exceptions anyway. In case of you think you can, you should be able to guess what can be go wrong anyway and know exact nature of error. I mean, in order to recover from that EDatabaseError, you should be able to think what you should do if user gives a wrong password beforehand. Otherwise you should just let the Exception be thrown. You dont catch the exceptions which you cannot do anything about it or you are not aware of.

In short, in your example, you should not catch and ignore all exceptions which you dont know. You will create more problems.
So, your example should be like below, in pascal/lazarus:

Code: Pascal  [Select][+][-]
  1. var
  2.   AConnection : TPQConnection;
  3.  
  4. begin
  5.   AConnection := CreateConnection;
  6.   try
  7.     try
  8.       AConnection.Open;
  9.       if Aconnection.Connected then
  10.         writeln('connected ok!');
  11.     except
  12.       on e: Exception do
  13.       begin
  14.         writeln('Error! Database connection failed : '+e.ToString);
  15.         // reraise exception here to stop current flow otherwise you will try to use this defunct
  16.         // connection to run queries and will create more problems
  17.         raise;
  18.       end;
  19.     end;
  20.     // You can use connection here if no exceptions are thrown otherwise here is skipped and it jumps to "finally" section
  21.     ...
  22.     AConnection.Close;
  23.   finally
  24.     // this is guaranteed to be executed. So you'll be sure that you wont create memory leaks, no matter what
  25.     FreeAndNil(AConnection);
  26.   end;
  27. end.
  28.  

Paul Breneman

  • Sr. Member
  • ****
  • Posts: 290
    • Control Pascal
Re: how to find out what exceptions might get raised
« Reply #5 on: June 04, 2017, 12:42:34 am »
Understanding the source of all the classes I use, seems like a overwhelming task, if I'm understanding SkyKan correctly. So, if I don't already know, somehow, what exceptions can get raised, I'm left with trying to discover them during testing and hope that I anticipate all the bad stuff that can happen.

Doesn't seem satisfactory.

Exception handling is an area where, I think, java's catch or declare requirement is better than what's currently available in object pascal.

The http://turbocontrol.com/embeddedfreepascal.htm page has this link http://codenewsfast.com/cnf/article/0/permalink.art-ng53q201750 to a Delphi discussion in 2001 about this topic, so you aren't the first to bring it up!
Regards,
Paul Breneman
www.ControlPascal.com

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: how to find out what exceptions might get raised
« Reply #6 on: June 04, 2017, 03:51:51 am »
Maybe I don't understand this, but as far as I understand you really need to reconsider the program structure. If someone is typing the wrong password then there should be a way to enter the password again (at least one time... depending on the security settings...). And without a proper password there should not be any connection.

On the other hand it's not necessary to know all the possible exceptions that can happen in a certain program at a certain point. Exactly for this there is TRY_EXCEPT_END without any special exception class. Then you catch all exceptions that can happen. If you like to do something special in case there is a certain exception, then you can figure out what exception class (for example: EDatabaseError) that is and do something in that case. But that is not necessary in general... you can, but there is no must.


For example:
Code: Pascal  [Select][+][-]
  1. Begin
  2.  Try
  3.   // Do something ...
  4.  Except
  5.  End;
  6. End;
  7.  
If you use this then any exception that occurs will be "terminated" and the user won't see anything of it. This is normally not a good idea, but can be used if you don't want to see any message. In case "Do something" is something that is visible to the user if it's not working and a message will only bother him...


Code: Pascal  [Select][+][-]
  1. Begin
  2.  Try
  3.   // Do something ...
  4.  Except
  5.   On E: Exception Do
  6.    Begin
  7.     Log('My Own Text....'+E.Message+sLineBreak+E.ClassName);
  8.     // set values back or close windows or free things... whatever ...
  9.    End;
  10.  End;
  11. End;
  12.  
This can be used if you want to use your own logging and if you need to do special things so that the program can secure run on if the exception won't crash the whole program...


Code: Pascal  [Select][+][-]
  1. Begin
  2.  Try
  3.   // Do something ...
  4.  Except
  5.   On E: Exception Do
  6.    Begin
  7.     Log('My Own Text....'+E.Message+sLineBreak+E.ClassName);
  8.     // set values back or close windows or free things... whatever ...
  9.     Raise;
  10.    End;
  11.  End;
  12. End;
  13.  
This can be used if you need to handle the exception at a higher level elsewhere in the code after you got your log and other things done.


Code: Pascal  [Select][+][-]
  1. Begin
  2.  Try
  3.   // Do something ...
  4.  Except
  5.   On E: Exception Do
  6.    Begin
  7.     Log('My Own Text....'+E.Message+sLineBreak+E.ClassName);
  8.     // set values back or close windows or free things... whatever ...
  9.     ShowMyLog;
  10.     Raise Exception.Create('ERROR xyz...');
  11.    End;
  12.  End;
  13. End;
  14.  
This can be used if you want your own exception name...

And if you use for example API functions (Windows) then you need to check the return value instead of using TRY_EXCEPT_END. Normally they won't throw exceptions...
Just my 2 cents...  :D
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

 

TinyPortal © 2005-2018