?
Solved

Consecutive exceptions (or nested exceptions) on Delphi

Posted on 2011-05-09
9
Medium Priority
?
926 Views
Last Modified: 2012-05-11
I'm writing a Delphi component, all brand new code. Note that it is a component, not an application.

I don't quite understand how exceptions are handled, when they are raised at several levels of the code.

I have an Object, that owns another object, which again owns and call methos from another object.
All method code is surrounded with try..except.

Now, when I get an exception on the 3rd inner object, this also causes the 2nd object to raise another exception, and this case the 1st object to cause another exception.
If I run the code through the debugger, I see this clearly, raising 3 exceptions.

But when I run my application outside the debugger I only get one exception: the last exception in the outer object.
I see this is the most practical way, but I'm losing the error message created in the inner objects, and I only see the more generic message I have in the code.

Clearly there's something wrong either in my design or my ideas on how to implement nested exceptions.
Could you please, provide some guide on how to do this? a sample, and article to read, any thing is appreciated.

Thank you!
 


0
Comment
Question by:fischermx
  • 2
  • 2
  • 2
  • +3
9 Comments
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35725956

The original message only disappears if you are displaying your own message, otherwise just pass through the original exception. In your except block, you can do this

   try
      //your code
   except
      on E: Exception do
      begin
         //do your cleanup code
         raise;    //re-raise the exception so that the message is not lost
      end;
   end;
0
 
LVL 1

Author Comment

by:fischermx
ID: 35726109
Hi, Ewangoya:

Yes, it seems I can do that for the 2nd and 3rd level. The message persisted.
But now, in the 1st level, I do want to add some other text, my own message, PLUS the original message (which actually comes from a 3rd party library).
I think I would need some system to aggregate error messages !?
0
 
LVL 38

Accepted Solution

by:
Geert Gruwez earned 1600 total points
ID: 35726581
to next exceptions and keep each message:

try this sample:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    procedure InnerCall;
    procedure OuterCall;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.InnerCall;
var
  Test: Integer;
  S: string;
begin
  try
    S := '';
    Test := StrToInt(S);
    Memo1.Lines.Add(IntToStr(Test));
  except
    on E: Exception do // catches the inner exception
      Raise Exception.Create('Inner error message raised in InnerCall: ' + #13#10 + E.Message);
  end;
end;

procedure TForm1.OuterCall;
begin
  try
    InnerCall;
  except
    on E: Exception do // catches the inner exception
      Raise Exception.Create('Inner error message caught in OuterCall: ' + #13#10 + E.Message);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    OuterCall;
  except
    on E: Exception do // catches the outer exception
    begin
      Memo1.Lines.Add('Outer exception caught in Button1Click : ' + #13#10 + E.Message);
    end;
  end;
end;

end.

Open in new window

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 7

Expert Comment

by:samenglish
ID: 35726590
If you raise exceptions trapped in your deeper methods, then you can access the text of those exceptions and add your own to it like this (example below)

try
  // your code
except
  on E: Exception do
    ShowMessage('Exception in my deeper method' + #10#13 + 'ClassName: '
                             + E.ClassName + '; Message: ' + E.Message);  // or format string as you like

end;
0
 
LVL 4

Expert Comment

by:fromer
ID: 35727270
For Evangoya's code,


   try
      //your code
   except
      on E: Exception do
      begin
         //do your cleanup code
         raise Exception.Create(E.Message + ' I want to add some detail');    //re-raise the exception so that the message is not lost
      end;
   end;
0
 
LVL 4

Expert Comment

by:fromer
ID: 35727296
OR .Net Approach...
make you own Exception class like,
 
MyException = class(Exception)
    protected
      FInnerException : Exception;
    public
      property InnerException : Exception read FInnerException;
      constructor Create(_Message : String; _InnerException : Exception);
  end;


constructor MyException.Create(_Message : String; _InnerException : Exception);
begin
  inherited Create(_Message);
  FInnerException := _InnerException;
end;

Open in new window


in the first level,

 
try
      //your code
   except
      on E: Exception do
      begin
         //do your cleanup code
         raise MyException.Create(E.Message + ' I want to add some detail', E);    //re-raise the exception so that the message is not lost
      end;
   end;

Open in new window


So you event don't lose the inner Exception class...
0
 
LVL 22

Assisted Solution

by:8080_Diver
8080_Diver earned 400 total points
ID: 35728307
To understand why you only see the one exception in the outer-most layer of your code, you have to think of each layer's call to the next lower layer as being independent and knowing nothing of any layers beyond the one called.  So, if your 3rd inner layer has an exception and your TRY . . . EXCEPT . . . code either re-raises that exception or raises a new exception, then the inner-most exception has been handled and, in effect, has been erased and replaced by the exception that is being raised in your EXCEPT section.  The 2nd inner layer then sees the exception that was raised by the 3rd layer's EXCEPT code and similarly reacts, in another EXCEPT section, by raising its own exception, which is then seen by the 1st layer.

I generally append the (usually ugly) error message from the original exception to a more human consumable message (and, especially while debugging, the routine in which the error occurred ;-) and then I raise a new exception in my EXCEPT code.  That way, the error message is both more intelligable by a user (although I do try not to have users see error messages ;-) and it provides a means of tracking the exact path that triggered the exception.  
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35728680
Yap, you can append the existing message to your custom message

   try
      //your code
   except
      on E: Exception do
      begin
         //do your cleanup code
         raise Exception.CreateFmt('Your message: ', [E.Message]);
      end;
   end;

0
 
LVL 1

Author Closing Comment

by:fischermx
ID: 35805625
Thank you!
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Screencast - Getting to Know the Pipeline
Suggested Courses
Course of the Month17 days, 4 hours left to enroll

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question