Recent

Author Topic: on try..except..  (Read 514 times)

Paolo

  • Hero Member
  • *****
  • Posts: 510
on try..except..
« on: March 17, 2023, 03:43:19 pm »
Hello,

I see that a common action can be used for all possible exception writing code like this (the code is meaninful just to illustrate the concept)

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. var
  3.   a, b, c : double;
  4. begin
  5.   try
  6.     a:=1;
  7.     b:=0;
  8.     c:=a/b;
  9.   except
  10.     MessageDlg('Something went wrong', mtError, [mbOK], 0);
  11.   end;
  12. end;
  13.  

I see that except section allows specialize the answer like this (Still covering all the possible exception thanks to “else”)

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button3Click(Sender: TObject);
  2. var
  3.   a, b, c : double;
  4. begin
  5.   try
  6.     a:=1;
  7.     b:=0;
  8.     c:=a/b;
  9.   except
  10.     on E:EZeroDivide do
  11.       MessageDlg('Division by 0', mtError, [mbOK], 0);
  12.     on E:EMathError do
  13.       MessageDlg('Computational Error', mtError, [mbOK], 0);
  14.     else
  15.       MessageDlg('Something unexpected went wrong', mtError, [mbOK], 0);
  16.   end;
  17. end;  
  18.  

Now my question: how implement an exception section that do something in ”all the cases” but then lefts the specialized case do the rest of the job? I would like something like

Code: Pascal  [Select][+][-]
  1. var
  2.   a, b, c : double;
  3. begin
  4.   try
  5.     a:=1;
  6.     b:=StrToFloat(Edit1.text);
  7.     c:=a/b;
  8.    except
  9.     //MessageDlg('Something went wrong', mtError, [mbOK], 0); <-- code needed for all exception cases, it does not compile
  10.     on E:EZeroDivide do
  11.       MessageDlg('Division by 0', mtError, [mbOK], 0);
  12.     on E:EMathError do
  13.       MessageDlg('Computational Error', mtError, [mbOK], 0);
  14.     on E:EConvertError do
  15.       MessageDlg('Conversion Error', mtError, [mbOK], 0);
  16.   end;
  17. end;
  18.  

How can I achieve this behaviour ? are there other ways to achieve this ?

Thank you

PascalDragon

  • Hero Member
  • *****
  • Posts: 5486
  • Compiler Developer
Re: on try..except..
« Reply #1 on: March 17, 2023, 03:52:59 pm »
Now my question: how implement an exception section that do something in ”all the cases” but then lefts the specialized case do the rest of the job? I would like something like

Code: Pascal  [Select][+][-]
  1. var
  2.   a, b, c : double;
  3. begin
  4.   try
  5.     a:=1;
  6.     b:=StrToFloat(Edit1.text);
  7.     c:=a/b;
  8.    except
  9.     //MessageDlg('Something went wrong', mtError, [mbOK], 0); <-- code needed for all exception cases, it does not compile
  10.     on E:EZeroDivide do
  11.       MessageDlg('Division by 0', mtError, [mbOK], 0);
  12.     on E:EMathError do
  13.       MessageDlg('Computational Error', mtError, [mbOK], 0);
  14.     on E:EConvertError do
  15.       MessageDlg('Conversion Error', mtError, [mbOK], 0);
  16.   end;
  17. end;
  18.  

How can I achieve this behaviour ? are there other ways to achieve this ?

One of the simpler solutions would be to add a nested exception handler block:

Code: Pascal  [Select][+][-]
  1. var
  2.   a, b, c : double;
  3. begin
  4.   try
  5.     try
  6.       a:=1;
  7.       b:=StrToFloat(Edit1.text);
  8.       c:=a/b;
  9.     except
  10.       MessageDlg('Something went wrong', mtError, [mbOK], 0); // <-- code needed for all exception cases, it does not compile
  11.       raise;
  12.     end;
  13.   except
  14.     on E:EZeroDivide do
  15.       MessageDlg('Division by 0', mtError, [mbOK], 0);
  16.     on E:EMathError do
  17.       MessageDlg('Computational Error', mtError, [mbOK], 0);
  18.     on E:EConvertError do
  19.       MessageDlg('Conversion Error', mtError, [mbOK], 0);
  20.   end;
  21. end;
  22.  

Paolo

  • Hero Member
  • *****
  • Posts: 510
Re: on try..except..
« Reply #2 on: March 17, 2023, 04:28:16 pm »
that was my fisrt idea, thanks

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: on try..except..
« Reply #3 on: March 17, 2023, 06:19:18 pm »
Exceptions are always class instances, so you can do this:
Code: Pascal  [Select][+][-]
  1. procedure ExceptionTest(toRaise: TObject);
  2. begin
  3.   try
  4.     raise toRaise;
  5.   except on E: TObject do
  6.   begin
  7.     WriteLn('Exception');
  8.     if E is EConvertError then
  9.       WriteLn('Convert Error: ' + Exception(E).Message)
  10.     else if E is Exception then
  11.       WriteLn(Exception(E).Message);
  12.   end;
  13.   end;
  14. end;
  15.  
  16. begin
  17.   ExceptionTest(EConvertError.Create('Convert')); // Exception + Convert Error Convert
  18.   ExceptionTest(EFormatError.Create('Format'));  // Exception + Format
In most cases the Exception will inherit from the Exception type from SysUtils, so you could even use this rather than TObject
Alternatively you might use AcquireExceptionObject, but then you extract that and have to ReleaseExceptionObject it afterwards

Thaddy

  • Hero Member
  • *****
  • Posts: 14377
  • Sensorship about opinions does not belong here.
Re: on try..except..
« Reply #4 on: March 17, 2023, 06:32:58 pm »
I am missing in all answers the quite essential
Code: Pascal  [Select][+][-]
  1.  else raise;
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Paolo

  • Hero Member
  • *****
  • Posts: 510
Re: on try..except..
« Reply #5 on: March 18, 2023, 10:49:40 am »
thanks to all for the suggestions

 

TinyPortal © 2005-2018