|
|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV SYS-CON.TV WEBCASTS |
POWERBUILDER LINKS YOU MUST CLICK ON PB & Java
The (New) Exception Call Stack Part 1 Of 2
By: Bob Hendry
Digg This!
In this issue Tim Nesham covers in-depth the TRY-CATCH-FINALLY block, which is new to PowerBuilder 8. But what is really happening behind the scenes? This article will give some historical background on PowerBuilder, but will also focus on PowerBuilder exception handling. When I first learned Java, I was amazed at how much it resembled PowerBuilder. The two languages are strikingly identical in how they implement inheritance and polymorphism. Over the past month, I have previewed PowerBuilder 8. Guess what? Power-Builder is starting to look like Java. What first caught my eye is how PowerBuilder 8 handles runtime errors. Before I discuss the new features, I would first like to cover how previous versions of PowerBuilder handle runtime errors. Let's begin with a history lesson.
Error Event
SystemError Event
So what's the big deal? Well, the problem with the "old way" is that error handling occurs far from the source. This can really limit how we can handle runtime errors. PowerBuilder 8 changes all this with "exception" handling. Exception handling allows programmers to deal with runtime errors, right at the source.
What's an Exception?
The exception object contains information about the exception, including its type and the state of the program when the error occurred. The runtime system is then responsible for finding some code to handle the error. In new terminology, creating an exception object and handing it to the runtime system is called throwing an exception. After a method throws an exception, the runtime system leaps into action to find someone to handle the exception. The set of possible "someones" to handle the exception is the set of methods in the call stack of the method where the error occurred. The runtime system searches backward through the call stack, beginning with the method in which the error occurred, until it finds a method that contains an appropriate exception handler. An exception handler is considered appropriate if the type of exception thrown is the same as the type of exception handled by the handler. Thus the exception bubbles up through the call stack until an appropriate handler is found and one of the calling methods handles the exception. The exception handler chosen is said to catch exception. The interesting premise of this technology is that Java handles runtime errors (now called exceptions) the same way. By using exceptions to manage errors, PowerBuilder has new advantages over traditional error management techniques:
Handling Code from "Regular" Code In traditional PowerScript, error detection, reporting, and handling often lead to confusing spaghetti code. For example, suppose you have a function that reads an entire file into memory. In pseudo-code, your function might look something like this:
of_readfile ( At first glance, this function seems simple enough, but it ignores all of these potential errors:
With error detection built in, your original seven lines have been inflated to 24 lines of code - a bloat factor of almost 400%. Worse, there's so much error detection, reporting, and returning that the original seven lines of code are lost in the clutter. And, worse yet, the logical flow of the code has also been lost in the clutter, making it difficult to tell if the code is doing the right thing. (Is the file really being closed if the function fails to allocate enough memory?) It's even more difficult to ensure that the code continues to do the right thing after you modify the function three months after writing it. Many programmers "solve" this problem by simply ignoring it - errors are "reported" when their programs crash. Now we have an elegant solution to the problem of error management: exceptions. Exceptions enable you to write the main flow of your code and deal with the, well, exceptional cases elsewhere. If your function used exceptions instead of traditional error management techniques, the pseudo-code would look something like that in Listing 2. Note that exceptions don't spare you the effort of doing the work of detecting, reporting, and handling errors. What exceptions do provide is the means to separate all the grungy details of what to do when something out-of-the-ordinary happens from the main logic of your program. In addition, the bloat factor for error management code in this program is about 250% - compared to 400% in the previous example.
Advantage 2: Propagating Errors Up
method1 ( Suppose also that method1 is the only method interested in the errors that occur within readfile. Traditional error notification techniques force method2 and method3 to propagate the error codes returned by readfile up the call stack until the error codes finally reach method1 - the only method that is interested in them (see Listing 3). PowerBuilder searches backward through the call stack to find any methods that are interested in handling a particular exception. A function can "duck" any exceptions thrown within it, thereby allowing a method farther up the call stack to catch it. Thus only the methods that care about errors have to worry about detecting errors.
method1 { However, as you can see from the pseudo-code, ducking an exception does require some effort on the part of the "middleman" methods. Any checked exceptions that can be thrown within a method are part of that method's public programming interface and must be specified in the throws clause of the method. Thus a method informs its callers about the exceptions that it can throw, so that the callers can intelligently and consciously decide what to do about those exceptions. Note again the difference in the bloat factor and code obfuscation factor of these two error management techniques. The code that uses exceptions is more compact and easier to understand.
Advantage 3: Grouping Error Types Furthermore, you can imagine that some methods would like to handle all exceptions that fall within a category (all array exceptions), and other methods would like to handle specific exceptions (like the null object references, please). Because all exceptions that are thrown within PowerBuilder are first-class objects, grouping or categorization of exceptions is a natural outcome of the class hierarchy. PowerBuilder exceptions must be instances of Throwable or any Throwable descendant.
Throwable Object
RuntimeError
One of the descendants of RuntimeError is the DivideByZeroError object type that is thrown by the application whenever this event occurs. This allows the handling of this type of error explicitly and immediately. Other descendants of RuntimeError include:
Exception
What's Next?
Try-Catch
The above code has at least three major problems. First of all, while we are performing division, what happens if we divide by zero? Furthermore, what happens if the window w_window is not currently open? Finally, the last line of code is trying to access an array element that does not exist. Does this code compile? You betcha. But there are at least three runtime errors that can occur. In this legacy piece of code, error handling would have to take place in the Application object's SystemError event. But not anymore. These runtime errors can be caught in a TRY-CATCH. As you will see the syntax is straightforward and easy to use. In PowerBuilder 8, the code would look like that in Listing 5. This is the simplest syntax of a TRY-CATCH. It works exactly like an IF statement. The code in the TRY is treated specially. If a runtime error occurs, PowerBuilder notes the type of runtime error that has occurred and looks to see if you "caught" it. If so, the code within the CATCH block is fired. Does this make sense? In the last portion of the code in Listing 5, we are catching a RuntimeError (which is the generic way of catching ALL runtime errors). Since a runtime error occurred in our TRY block - rather than the user crashing and burning - the user is shown a friendly message and we all can breathe a sigh of relief. Can multiple lines exist in a TRY-CATCH? Yes. Take the following code example:
try In this example, if any runtime error occurs within the TRY block, the code in the CATCH is fired. Here we are displaying the nature of the system error via the getMessage method on the RuntimeError class. What can you do with an exception once you've caught it? It's really up to you.
Catching Multiple Exceptions
In this code, if multiple blocks match the exception type, the first block that matches the type of the exception catches it.
Next Month
PBDJ LATEST STORIES . . .
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING POWERBUILDER / SYBASE NEWS
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||