Monday, March 5, 2012

Don't break on all exceptions

In a recent post on Real Software's blog, Paul Lefebvre wrote about some useful pragma commands. But there was one he didn't mention that I've found to be useful in many cases and which was introduced in the 2009r2 release:

#pragma BreakOnExceptions On | Off | Default

When I'm working on a project in the IDE, I always leave the 'Break On Exceptions' menu item checked. I'm the kind of programmer whom is afraid of missing a special and random exception condition running a project in the debugger. I just can't help it, even if it proved useful only once or twice since I'm using Real Studio ( REALbasic 2.1 actually ). The 'dark' side is that each time an exception is raised, the debugger kicks in. Even if this exception condition is expected and properly handled.

Let's see an example with a simple CreateFile() function that takes a FolderItem as parameter and returns a boolean that is True if the creation was successful, and False if it wasn't:

Function CreateFile(inFile As FolderItem) As Boolean

  // Create the binary stream
  Dim theStream As BinaryStream
  Try
    theStream = BinaryStream.Create( theFile )
  Catch theIOException As IOException
    // Do some logging
    System.DebugLog CurrentMethodName _
        + ": Failed to create " + theFile.ShellPath
    // Inform the caller that it failed
    Return False
  End Try
  // Write to the stream
  theStream.Write "Some data"

  // test for write error
  // [...]

  // Close the file.
  theStream.Close
  // the creation was successful
  Return True

End Function


If you're testing a batch process of dozens or hundreds of files for which some exceptions can occur, you don't want the debugger to kick in each time. So I'm doing this:

Function CreateFile(inFile As FolderItem) As Boolean

  // Create the binary stream
  Dim theStream As BinaryStream

  #pragma BreakOnExceptions Off '<--- added a pragma

  Try
    theStream = BinaryStream.Create( theFile )
  Catch theIOException As IOException
    // Do some logging
    System.DebugLog CurrentMethodName _
        + ": Failed to create " + theFile.ShellPath
    // Inform the caller that it failed
    Return False
  End Try

  #pragma BreakOnExceptions Default '<--- added a pragma

  // Write to the stream
  theStream.Write "Some data"

  // test for write error
  // [...]

  // Close the file.
  theStream.Close
  // the creation was successful
  Return True

End Function


With these pragma commands, the debugger won't show up whenever an IOException is raised during the BinaryStream creation attempt. And if you need to know about the file paths that failed to be created, you can list them in Mac OS X console, Windows' debugger or Linux's StdErr . You can even log the IOException.ErrorNumber property's value for more information on why it failed.

Now, by using this pragma wherever the code properly handles exceptions, you can concentrate on real unexpected exception conditions.

1 comment:

  1. Thanks a lot for this little article about pragma. This was a really neat tip, since I myself sometimes turn off the exception break completely and then forgets to turn it on again, and you know what happens when you forget to turn on the exception break? THat tiny extremely rare occurring bug will guaranteed to be showing up, crashing ur app just ONCE, leaving your mind clueless and worried for the rest of your life wondering what happened that one time you can't replicate. This pragma tip gonna save me from this problem. THanks man!

    ReplyDelete