Exercise caution with catch clauses

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 🙂