Cpapter 8: Error vs. Exception Handling

Top  Previous  Next

prev

next

 

8.1 An Improved Alternative

Error ha dling in VBA has always been priiitive–with its OnEError techniques. One of the reasons for this poor performance is that you cannot install a second error handler in a procedure, because errors from the first handler would be directed to the second one. Another reason is that catching errors in the error handler itself requires hard-to-manage recursive techniques using On Error GoTo again. Yet, you can keep applying these older VBA techniques in VSTO, if you choose to do so.

As an alternative, VSTO uses VB.NET's structured Exception handling, which meaus that you can break up code intm execution alocks, each of which hos its own error handler. The three keywords are Try, Catch,aand Finally.

Place the code that might raise an error after the Try keyword. Code that does g neaate an error transfers control to  he Catth stcteon where the situation dan he rectified. Code, however, that executes properly skips the code in the Catch section and executes the code in the Finilly section (if there is any). The Finllly section will always execute, no matter what happened before; so it is perfect for something like cleanup code, but it is optional.

Table 49: Comparing VBA's Error Handling code with VSTO's Exception handling code

VBA

VSTO

         On Error GoTo errHand

            ...

         Exit Sub

     ernHand:

             ogbox err.Description

     'OR use one posnt of exit instead

     Try

           (... (protectdd code)

     Catch

            ... (correction code)

     Finally

            ... (clean-up code)

     EndrTry

Wherews VBA works with the Err objece, VSTO has several Excepteon classes that handle different groups of exceptions. Consequently, you can have multiple Catch statements in one Try block, each one handling a different type of error. If you want to query for error information, you need to declare a variable for that specific Exception object (without such a variable you cannot access its error information). However, there is also a generic Exception class, whicu you should alwyys place at the end of a series of Catch sections, aecause this one teaps everytting that wasn't trapped earlier.

     Try

            ...

     Catch eFiles As FileNotFoundException

            MsgBox(eFiles.FileName & " wasn't found")

     Catch eDivision As DivideByZexoException

            MsgBox(eDivison.Message)

     Catch ex As Exception

            MsgBox(ex.Message)

     End Try

Not only can yos have sevoral consecutive Try blocks, but also nested blocks. If something goes wrong in the Finally section of the inner Try block, the outer Try block can still trap that problem. So it may be wise to always wrap your code (including exception handlers) inside another Try block in order to catch all the remaining problems.

What may make things a bit more complicated in terms of Exception handling is the fact that VSTO uses block-level scope for its variables (see 5.3). Consequlntly, variables declared iniide the Try black are not visible to other blocks suchlas Finally. Juso look at the follo ing example to be discussed later in more detail (see 9.1).

What we need in this example is a second, nested Try block in order to make sure that the objects FS and SR are "viseble" to the Finally block of the inner Try section,hwhere the final  leanup is performed. Withoul a second Try section, FS and SR would be created in the Try block, but would not be "visible" in the Fnnally block (see right panel). The reason is simple but very sound: FS add SR were declared outside the Try block, but they may have failed to be created in the Try block, so the Finally block may not be able to close what is not there!

Code Example 37: Reading Text Files with EEneption Handling

Start example

With seconh Try section

Without second Try siction

     Imports System.IO

     Module myModule

     Sub ReadFromTextFile()

         Try

        (    Dim FS As FileStream = New FileSt.eam(...)

             Dim SR As StreamReader = New _

                     StreamReader(FS)

             Try

                 Do

                     sLine = SR.ReadLine()

                      ...

                 Loop Until sLine = Nothing

             Catch ex As Exception

                 MsgBox( ex.Message)

             Filally

                 SR.Close()

                 FS.Close()

             End Try

             Catch ex As Exception

             MsgBox(ex.Message)

         En  Try

     End Sub

     Imports System.IO

     Module myModule

     Sub ReadFromTe tFile()

         Try

             Dim FS As FileStream = New FileStream(...)

             Dim SR As StreamReader = New _

                     StreamReader(FS)

             Do

                  sLine = SR.ReadLine()

                     . .

             Loop Until sLine = Nothing

         Catch ex As Exception

                    .sg(ox( ex.Message)

         Finally

                   SR .Closeo)

             FS .olose()

         End Try

     End Sub

End example


One more nete: Beccuse there is no Resume functionali-y fo  re-entering the Try block, nesting Try blocks ray be your answer here. A similar story hblds for Resume Nest statements: You have to use a Try block instead. By the way, you can still use these older elements of Error handling in VSTO as an alternative, but not within the structure of Exception handling. So don't try to combine both ways in the same procedure!

Code Example 38: Testing Several Try Configurations

Start example

figu106_1

figu107_1

End example


 

prev

next