delphimadexcept

MadExcept + try/finally block?


I have some delphi code, kind of like this:

try
  //some code
  //occasionally throws an exception here, for example an EIndexOutOfRangeException
  //more code...should get skipped if exception is thrown
finally
  // there may or may not be any important cleanup code here
end;

The exception in this case is not something that needs handling beyond breaking out of the try block. So, before mad-except was added to the project for error troubleshooting, this code was "working". But now I'm getting bug reports because MadExcept is reporting the uncaught exception.

Related question, MadExcept triggers on try finally indicates the behavior of MadExcept breaking in such circumstance is "expected" because the exception isn't "handled".

I would like some clarification about what my options are as far ways to prevent a mad-except dialog from popping up when this code runs, regardless of whether there's an internal exception being thrown and ignored.

So I'm correct in thinking there's no switch to disable MadExcept from breaking on unhanded exceptions in a try/finally block? And I'm going to need to explictly "catch" the exception even if I wish to ignore it?

Should I be doing something like this (ignore any exception):

try
  //some code
  //sometimes throws EIndexOutOfRangeException here
  //more code...should get skipped if exception is thrown
except do begin end;
end;

or perhaps (ignore a very specific exception):

try
  //some code
  //sometimes throws EIndexOutOfRangeException here
  //more code...should get skipped if exception is thrown
except on E : EIndexOutOfRangeException do begin end;
end;

or maybe it needs to be:

try
  try
    //some code
    //sometimes throws EIndexOutOfRangeException here
    //more code...should get skipped if exception is thrown
  except on E : EIndexOutOfRangeException do begin end;
finally
  // some cleanup code
end;

If all three of those are valid solutions, should I prefer one over the other for any reason?


Solution

  • So I'm correct in thinking there's no switch to disable MadExcept from breaking on unhanded exceptions in a try/finally block?

    Yes. try/finally is not exception handling; it's guaranteed cleanup, whether or not an exception occurs. As such, try/finally blocks are completely irrelevant to exception handling tools such as MadExcept.

    And I'm going to need to explicitly "catch" the exception even if I wish to ignore it?

    Yes. That's how exceptions work. They work their way down the stack until they find a handler that catches them. If no such handler exists, the OS interprets it as a crash and terminates the program. Delphi's TApplication object installs a handler very close to the bottom of the call stack so that your program won't crash, and MadExcept hooks this so that if an exception reaches this point, a report will be generated.

    If you want to ignore an exception, yes, you do need to catch it, because what you are doing is formally "handling the exception by catching it at this point in the stack unwinding and ignoring it." That part about "catching it at this point in the stack unwinding" is important, since it means that the stack unwinding halts at that point and the program resumes normal execution. If you just ignored it, (ie. did nothing about it in your code, including not installing an exception handler,) it would continue to unwind the stack all the way to the default handler, whether or not you had MadExcept installed.

    So yeah, in this case, example #2 is the correct course of action. Example #3 would be valid too, if you have cleanup code that needs to be performed at this point. But example #1 should never be done under any circumstances because it means you might end up ignoring an exception that you were not anticipating, and then you end up with corruption in your program and you never become aware of it.