Mar 232018
 

A colleague of mine asked me today, how this could be:

Given this exception handler:

try
  // some code that calls methods
except
  on e: Exception do
    LogError(e.Message);
end;

How could e be nil? (and e.Message result in an Access Violation?)

It turned out to be an error in one of the methods that were called:

if SomeCondition then
  raise Exception('some error message');

Can you spot the problem here? For whatever reason the .Create call is missing! So instead of an exception object raise was working on a string typecasted to exception.
Changing it as follows fixed the error:

if SomeCondition then
  raise Exception.Create('some error message');

We did a grep search for “raise Exception(” in our code base and found 4 more cases where this problem existed. 4 bugs less, probably still quite a few to go.

But even worse: Greping for “raise e[a-z]*(” turned up two more cases. One in my own dzlib (unit u_dzVclUtils), another in the jcl (That one has already been fixed, my copy is a bit dated.).

Edit:
In the comments to the corresponding Google+ post, David Hoyle pointed out another common mistake regarding exceptions: Forgetting to actually raise them:

if SomeCondition then
  Exception.Create('some error message');

So, I did a grep for ” e[a-z]*\.Create\(” and found several, one in the (old) SynEdit version used in GExperts, several in Indy 10 and JVCL (old versions again) and one in System.JSON.Types of the current Delphi 10.2.3 RTL (RSP-20192). None in my own code this time. 🙂