Link to home
Start Free TrialLog in
Avatar of fischermx
fischermxFlag for Mexico

asked on

Consecutive exceptions (or nested exceptions) on Delphi

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!
 


Avatar of Ephraim Wangoya
Ephraim Wangoya
Flag of United States of America image


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;
Avatar of fischermx

ASKER

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 !?
ASKER CERTIFIED SOLUTION
Avatar of Geert G
Geert G
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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;
Avatar of fromer
fromer

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;
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...
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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;

Thank you!