Exception HandlingRuntime Exceptions
Runtime exceptions are how REALbasic informs you that a problem has occurred. It offers yet another wrinkle to object-oriented programming. It's a class and it can be subclassed. You should create your own exception classes because that will give you more control over how errors are handled. At the same time, exceptions are capable of behavior that is unique to exceptions. Exceptions are raised, which is not unlike triggering an event. Recall that when a
An all-too-common exception is
NilObjectException
, which occurs when you try to access an object that has been declared but not
"Handling it" from REALbasic's perspective means returning true . If you do not do this, the program will exit. It's pretty bad form to have an application crash uncontrollably, and this gives you an extremely easy way to add a little grace to the unexpected error. Ideally, within this event, save any files or data that you can so that as little work as possible is lost. Try...Catch...End/Finally
I find this the most
Sub someMethod(anObject as SampleObject) Try anObject.aMethod Catch err as NilObjectException anObject = New SampleObject() anObject.aMethod End End Sub
If you have code that you want to execute regardless of the outcome, you can use Finally, as
Sub someMethod(anObject as SampleObject) Try anObject.aMethod Catch err as NilObjectException anObject = New SampleObject() anObject.aMethod Finally // the rest of the method End End Sub You can replicate this functionality simply by testing values:
Sub someMethod(anObject as SampleObject) If anObject <> Nil Then anObject.aMethod Else anObject = New SampleObject() anObject.aMethod End If End Sub
The limitation to this approach is that you have to explicitly test for each kind of error. In this example, all that's being
LoggingUse System.DebugLog to send messages to the screen about the state of your application during debugging.
System.DebugLog(aMessage as String) It works slightly differently on each platform. On Windows, you will need a debugger to view the output. A good (and free) debugger is called DebugView and is available here:
http://www.sysinternals.com/Utilities/DebugView.html On Macintosh, you can use the Console application to view the message, and on Linux, the output is sent to SdtErr (you'll need to start the application from the terminal to see the messages). The use of DebugLog is best for sending messages that you want to view while the application is running. This is a much better alternative than using things like MsgBox to identify the current state of your program. Bear in mind that consistently writing to the console will impact the performance of your application, so you should distinguish between "debugging" and regular logging. One simple way to do this is to use compiler directives. The following snippet means that the data will be logged only when you are in DebugMode , which is when you are running an application from the IDE. It will not log this information after the application has been compiled:
#if DebugMode then
System.DebugLog("Some message")
#endif
The System object also offers the System.Log method:
System.Log(logLevel as Integer, message as String) The use of a logLevel allows you to specify the nature of the debugging or logging message. The class constants are as follows:
System.LogLevelAlert as Integer System.LogLevelCritical as Integer System.LogLevelDebug as Integer System.LogLevelEmergency as Integer System.LogLevelError as Integer System.LogLevelInformation as Integer System.LogLevelNotice as Integer System.LogLevelSuccess as Integer System.LogLevelWarning as Integer When using System.Log , the output is sent to EventWatcher on Windows. Macintosh users can use Console again, and Linux users can usually find the file in /var/logs . The reason for the levels is that applications like EventWatcher and Console are able to filter messages, so you may configure it to only show you the errors, if that's all you want to see, or you can look at everything. You may want to use System.Log all the time that your application runs, unlike SystemDebug . There are a lot of reasons for doing this, but often it's used for applications that run unattended so that the logs can be reviewed at a later date. Note that even though there are different levels, the messages are all written to the log, even if you have them filtered in the viewer. In some cases it makes sense to make the level of logging detail configurable, and it's very easy to do. All you really need is a method that wraps the System.Log method and determines, based on preferences or something similar, whether to actually write out the message to the log. One scenario is to create a module called myLog with a method, Logger , that you send all the logging messages to:
myLog.Logger(System.LogLevelError, "An error!") The module could also have some properties that define which messages get logged:
myLog.Debug as Boolean myLog.Warnings as Boolean myLog.Errors as Boolean // and so on
The
myLog.Logger
method would
Sub Logger(logLevel as Integer, message as String)
If logLevel = System.logLevelDebug and myLog.Debug Then
System.Log(logLevel, message)
End If
If logLevel = System.logLevelWarning and myLog.Warnings Then
System.Log(logLevel, message)
End If
If logLevel = System.logLevelError and myLog.Errors Then
System.Log(logLevel, message)
End If
End Sub
Debugger
In one way or another, debugging
This is where REALbasic's debugger comes into play. REALbasic has an
Figure 5.22. Debugging code.
This is great, because now you don't have to write a line to a log file for
There are three ways you can make your program pause and view the information in the debugger. The first is with the Break statement. You can add it to particular
Finally, you can tell REALbasic to break every time there is an exception. This is a good thing to do to help you track down exceptions and see what might be
After you break, you can do two things. First, you can examine the values of any object that is running your application as shown in Figure 5.23.
Figure 5.23. Examine the values of
|