Illegal Locking Exception

Your program is terminating because it has reached an exception it wasn’t designed to handled. That’s how the UnhandledException system is supposed to work.

If you can handle the exception, catch its type specifically, handle it, and carry on.
If you can’t, it needs to bubble and, for the third time, your app needs to Terminate.

I disagree. If it is handled by a outer handler that is not true.

Then, that outer handler as part of “catch its type specifically, handle it, and carry on” needs to unlock the CriticalSection. I shouldn’t have to iterate over every possible design to get the point across of when finally is executed.

For clarity it would not be executed if an exception were handled by an “outer handler”. The code would carry on from that “outer handler” catch statement.

I fully agreed what Finally does long ago.

That outer handler should not be dealing with the Critical section, it has no knowledge of the its state

Reading the documentation on Finally. There is an alternative version that makes sense in this circumstance:

Var CSEntered as Boolean = false
Try
   CriticalSection.Enter
   CSEntered = True
   DB.BeginTransaction
   [Do sqlite things that do not directly or indirectly involve entering or leaving critical section]
   DB.CommitTransaction

Catch oError as DatabaseExcpetion
   DB.RollbackTransaction

End Try

// This Finally operates even if there is an unhandled exception.
Finally
   if CSEntered then CriticalSection.Leave

Notes: Sometimes a method needs to do some cleanup work whether it is finishing normally or aborting early because of an exception. The optional Finally block at the end of a method or function runs after its exception handlers, if it has any. Code in this block will be executed even if an exception has occured, whether the exception was handled or not.

1 Like

That is another form of the “catch all” design I have recommended against.

There seems to be a misunderstanding about Try...Finally. The Finally clause will execute regardless of the number or type of Catch clauses.

Consider:

Try
  Raise New DatabaseException

Catch Err As UnsupportedFormatException
  Break // Never executed

Finally
  Break // always executed

End Try
Break // executed only if no exceptions are raised and uncaught

The only way the Finally clause would not execute is if there is a Return statement in the Catch clause.

Try
  Raise New DatabaseException
Catch Err As DatabaseException
  Return // don't do this
Finally
  Break
End Try

Not if there is an Exception that is not handled. Nothing after the line that causes the exception executes. The difference of opinion is if the Critical section should be "leave"d if an unhandled exception occurs.

Whether the exception is handled is irrelevant. You don’t even need a Catch:

Try
  Raise New DatabaseException
Finally
  Break // always executes
End Try

The exception will still propagate, but Finally will execute before it does.

The point I was trying to make is that

Finally
  Break // always executed

and

End Try
Break // always executed

are functionally the same break.

One will always get both breaks or neither break. One would never get just one of them. The code from your // don't do this example would operate functionally the same as well.

Sorry Tim that is not the case this does not cause a break. Just tested in IDE.

Try
   Raise New DatabaseException
End Try
Break // never executes

Andrew is correct, however, about this:

Try
   Raise New DatabaseException
Finally
   Break // always executes
End Try
1 Like

We’re getting into whataboutism now, and I’m not going to play that game.

I think how Finally works is subtle, and not necessarily intuitive - but definitely useful.

Imagine this code:


App.unhandledException
  system.DebugLog "E App.UnhandledException"

App.Open
  try 
    system.DebugLog "A Try: about to raise exception"
    raise new RuntimeException
    system.DebugLog "B Try: after exception"
  finally
    system.DebugLog "C Finally clause running"
  end try
  system.DebugLog "D After End Try"

What you get is this:

A Try: about to raise exception
C Finally clause running
E App.unhandledException

To me this is interesting, as the Finally clause happens before the exception bubbles up out of the method.

3 Likes

Very much so. I will have to consider this when I use exceptions in the future.

I apologise if it came across as having any malicious intent. That was certainly not my intention. I’ll leave it there.

3 Likes

Thanks all for the discussion. I am much better informed now.

1 Like