Try Catch Finally

Xojo supports the use of exceptions and the error handling machnisms that makes possible.

in order to use exceptions effectively you need to use a language feature called a Try block. It has several parts to it. First there is the initial TRY statement which opens a new scope level AND delimits where the TRY block starts. Its entirely possible to simply have code like

TRY
   // some code enclosed by the block
END TRY

You are not forced to have a CATCH statement in a try block. This style can be useful if, for instance, in the try portion you assign a value to a variable when there is no exception raised and then check that variable after the block and behave accordingly. Perhaps something like

dim f as Folderitem
TRY
   f = SpecialFolder.ApplicationData.Child("my.app.bundleID")
END TRY

if f is nil then
   f.CreateAsFolder
end if

But not that this code _could_ have an issue of for some reason SpecialFolder.ApplicationData is nil. We didnt check that and should before just blindly using it. There are other ways to accomplish much the same task by dealing with whatever exceptions are raised. For instance you might rewrite the above code to

dim f as Folderitem
TRY
   f = SpecialFolder.ApplicationData
   f = f.Child("my.app.bundleID")
CATCH nilError as NILObjectException
   // hmmm this means SpecialFolder.ApplicationData is nil ?
   // we might show an error dialog to the user or something to 
   // let them know that the folder we were trying to create cant be 
   // created in the SpecialFolder.ApplicationData location 
   // and we might return here rather than try to carry on
END TRY

if f is nil then
   f.CreateAsFolder
end if

This style at least makes it so we have checked whether or not SpecialFolder.ApplicationData was nil – its unusual that it might be but can happen.

You can have as many CATCH statements as you want and they can be written in many different styles. Personally I always use the form

Catch ErrorParameter As ErrorType

with a name for the error parameter; which actually ends up being a local variable in the CATCH code you write, and a specific type. In my code you might see

TRY
CATCH noExc as NilObjectException
  // code to deal with the Nil Object Exception
CATCH ioExc as IOEXception
  // code to deal with the IO Exception
END TRY

and specific code where noted by the comments to deal with the situation. I do not recommends using a single catch with a long list of select statements using introspection etc to try and handle the various exceptions. The only time I might recommend that is when its the App.Unhandled exception event and you are trying to create a report that a user can send you. Even there you have to be careful of which exceptions you catch because a normally Quit application uses an exception to Quit normally.

The last part of a TRY CATCH block is the FINALLY block. This is code that runs after all the code in any TRY or CATCH sections executes. Some times there is code that you want to execute as part of clean up that needs to release memory, mutexes, semaphores etc.

However, some assume that it will ALWAYS execute regardless of what code you have in the TRY and CATCH portions. In some languages the code in the FINALLY block is ALWAYS executed. This is NOT the case in Xojo and, if you’re not careful, it CAN easily be skipped.

For instance, if you use RETURN as the last line of the TRY or a CATCH block that is executed the FINALLY block WILL be skipped.


Try
  Raise New NilObjectException
Catch
  Return
Finally
  Break
End Try

If you execute this code you will see that the BREAK in the finally block is NOT executed. And if you changed this to


Try
  Return
Catch
Finally
  Break
End Try

Again you will see the break in the finally clause is not executed. So be careful about the use of return in a TRY CATCH block IF you expect the FINALLY clause to always be executed.