1. Computing

Reraising Exceptions in Delphi - How to Properly - A Poll

By February 21, 2012

Follow me on:

in Exception Handling :: Exceptions are special conditions in your code that require special handling. Exceptions include errors that occur at run time like divide by zero, database errors, freeing the object twice and alike.

Related:

Lucky for us, Delphi developers, whenever an error results from processing a line of code, Delphi creates (raises) an object, descending from TObject, called the exception object. This is again handled by Delphi, which (by default) catches exceptions and calls Application.HandleException - displaying the error dialog.

You can fine tune exception handling, in your application code, by responding to an exception either by executing some termination code, handling the exception, or both.

Now, let's say you need to re-raise an exception in your code handing exceptions. You would reraise the exception if it is not the one you know how / want to handle specifically.

The poll question is: do you know the proper way of reraising the exception?

Here's some code raising some exceptions:

type
  EEvenException = class(Exception);

var
  x : cardinal;
begin
  x := GetTickCount;

  try
    if x mod 2 = 0 then
      raise EEvenException.Create('tick even')
    else
      raise Exception.Create('odd exception');
  except
    on E : EEvenExcpetion do { handle "tick even" } ;
    on E : Exception do { ?? reraise ?? };
  end;
end;
The code above is dummy - and therefore not the best way to demo raising exceptions - so let's just concentrate on the except block.

If GetTickCount is even number the EEvenException is raised. If odd a generic Exception is raised. Let's say I know how to handle even ticks, but want to reraise the exception if ticks are odd.

And here's the question: what should go for "{ ?? reraise ?? }"?

Comments
February 21, 2012 at 8:33 am
(1) Hallvard Vassbotn says:

In this case the correct way is to remove the “on E : Exception do” part altogether. The compiler already creates code that only handles EEvenException and lets all other exceptions on to outer stack levels.

You would only use “raise” to re-raise if do something (log, change original exception message, create new exception class) and then want to reraise the original or new exception.

February 21, 2012 at 9:17 am
(2) Zarko Gajic says:

@Hallvard: Thanks for a note. As I mentioned, the code is a dummy one and we should only concentrate on the question: “how to properly reraise the exception” in the except block.

February 21, 2012 at 4:57 pm
(3) Anton Alisov says:

Reraising an exception in a case like yours may be useful we need to add some additional info about the lower level exception at the higher level. This is required very often, because as usual low level exceptions contain too little information about the error. Such messages don’t help the user to understand what really happened and don’t help programmer to identify the conditions that lead to error. Examples of such messages are “Access violation at …”, “Ole error XYZ”, “Division by zero” etc.

Code sample:

procedure Save;
begin
try
CheckEverythingOk;
DeleteOldData;
AddNewData;
except
on E: Exception do
begin
E.Message := ‘Saving failed: ‘ + #13#10 + E.Message;
raise; // here I reraise the exception with modified message
end;
end;
end;

In this code if I get an exception from CheckEverythingOk, DeleteOldData or AddNewData methods, I’ll get the message, stating that this error happened during saving.

February 21, 2012 at 6:05 pm
(4) N@ says:

Using “raise E;” can sometimes cause an access violation… You should never do it. You either use “raise;” or raise a new exception object.

November 8, 2012 at 9:21 am
(5) Fred says:

“Re-raising” an already raised “E” exception instance would indeed cause an access violation BECAUSE the VCL normaly free the exception at the end of a try/except block. So, you have to use the AcquireExceptionObject method.

This example re-raise an exception and wrap the whole thing into another one:

try
AcquireExceptionObject();
raise E; // re-raise a given Exception instance E
except
Exception.RaiseOuterException(Exception.Create(‘Here I re-raised an exception, look at my innerException for more details’));
end;

That’s it.

Leave a Comment

Line and paragraph breaks are automatic. Some HTML allowed: <a href="" title="">, <b>, <i>, <strike>

©2014 About.com. All rights reserved.