Xojo now generally uses exceptions to handle errors.
And with that comes some things you should know about how exceptions work that you need to be aware of before you cause yourself problems.
First off, in my opinion, you should put your try catch blocks as close to the code that causes the error. While Xojo lets you use one EXCEPTION or CATCH block at the end of any method like the following
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
Catch foo As RuntimeException // or Exception foo as RuntimeException
Break
I would suggest you avoid this form. It’s not obvious unless your methods are VERY short and it on one screen of code. For instance, does the following method have a catch ? Without actually looking at the very end you cannot tell (In fact it does but that isnt clear)
As well using a single consistent form is probably a better practice than sometimes using this form and sometimes using other forms. Even if the entire method is surrounded in a TRY CATCH block its more obvious. This is the exact same method with the addition of the TRY keyword at the very beginning and “END TRY” at the very end
try
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
// do a bunch of code
Catch foo As RuntimeException
Break
End Try
The other thing to be careful about is how you write your catch statements. The documentation shows a legal CATCH statement as
Catch [[ErrorParameter] [As ErrorType]]
Note that EVERYTHING except the CATCH keyword is optional. Again I would suggest you almost NEVER use just a CATCH by itself as you will catch every type of exception, perhaps even those you cannot actually handle.
The other thing that is often confusing is if you write
Catch someException
which is legal what you have in fact got is
Catch someException as RuntimeException
and the local variable is name someException. Save yourself the grief and ALWAYS use the fully spelled out form of CATCH like
Catch <localVariableUsableInTheExceptionHandlingCode> as <ExceptionType>
Using it this way insures you are never surprised at catching more than you were prepared to handle. Also note that the localVariableUsableInTheExceptionHandlingCode is in fact defining a local variable that you can use in the body of this specific CATCH block. What that means is code like
Catch iox as IOException
system.debuglog iox.errormessage
is legal and, in this case, iox is usable within the rest of the code following that catch until you get to another catch, the finally block, or the end try. The following WOULD NOT be legal
Catch iox as IOException
system.debuglog iox.errormessage
Catch oob as OutOfBoundsException
system.debuglog iox.errormessage
iox would not be in scope in the code following the catch of the out of bounds exception. Nor would oob be usable in the block handling the IOException.
And this last example shows something you can legally do. You can have more than one catch statement. The only thing you need to be careful about here is not catching the most general types before the more specific ones. What do I mean by that ?
Since all exceptions are descendants of RuntimeException they are more specific types of exceptions than RuntimeException is. If your code was like
Try
Raise New nilobjectexception
Catch rte As RuntimeException
Break
Catch noe As NilObjectException
Break
End Try
you would find that any code following the catch of the NilObjectException would NOT get executed. Because NilObjectException is descended from RuntimeException the first catch block will handle EVERY exception. Changing this code to
Try
Raise New nilobjectexception
Catch noe As NilObjectException
Break
Catch rte As RuntimeException
Break
End Try
will now execute the NilObjectException code since that matches the more specific type. Note this is not peculiar to try catch statements but a general thing to keep in mind when dealing with if then else, select case and other kinds of statements that use boolean values to determine if their code should execute.
Now go catch stuff 🙂