Code Focused

Life Without On Error Resume Next

The alternative to that simple error-handling combo is the Try...Catch, but it's not as simple as wrapping up your code with it.

Long before .NET arrived on the scene, the On Error statement in Visual Basic formed the foundation of that language's error management options. Through the judicious use of On Error GoTo statements and related error objects, you could craft error-handling code that was every bit as rugged and nearly as structured as the modern Try...Catch alternative. But when you didn't care anymore, there was this:

On Error Resume Next
DoSomethingUnsafe()
HereIsMoreDanger()

The On Error statement's Resume Next clause told the world, "Do what you want; ask me later if I care." It was a great way to ignore low-risk errors in your source code. But when misused, the statement could greatly complicate debugging and data issues. And, yet, there were times when it was the right tool. The cleanup of low-priority resources just before exiting an application is an example that comes to mind:

On Error Resume Next
resourceOne.Cleanup()
resourceTwo.Cleanup()
resourceThree.Cleanup()
End

When migrating such code to its structured alternative, the temptation is to wrap it all up in one large Try statement:

Try
  resourceOne.Cleanup()
  resourceTwo.Cleanup()
  resourceThree.Cleanup()
Catch
  ' ----- Ignore any error.
End Try
End

Unfortunately, this isn't the correct conversion, because any exception thrown by the cleanup of resourceOne will cause the code to completely skip the two remaining logic lines. A more accurate translation into modern .NET code would provide error handlers for each trouble-prone statement, as shown in Listing 1.

Listing 1: The Correct Way To Use Try…Catch
Try
  resourceOne.Cleanup()
Catch
  ' ----- Ignore any error.
End Try
Try
  resourceTwo.Cleanup()
Catch
  ' ----- Ignore any error.
End Try
Try
  resourceThree.Cleanup()
Catch
  ' ----- Ignore any error.
End Try
End

The code in Listing 1 is correct, and it provides task-specific opportunities to deal with any errors that do occur, even when moving from a procedure that formerly tossed caution to the wind.

Despite the validity of this code, you might wonder how the Visual Basic .NET compiler deals with On Error Resume Next. By building your Visual Basic project, and then extracting out the compiled result using the .NET Framework Intermediate Language (IL) Disassembler tool (ILDASM.EXE), you can see exactly what the compiler does. It's IL, so it's not pretty. But the Visual Basic code presented in Listing 2 shows generally what the compiler attempts to do.

Listing 2: What the Compiler Tries To Do, in Visual Basic
Dim position As Integer
Try
  position = 1
Statement01:
  position = 2
  resourceOne.Cleanup()
Statement02:
  position = 3
  resourceTwo.Cleanup()
Statement03:
  position = 4
  resourceThree.Cleanup()
Statement04:
  position = 0
  GoTo EndOfLogic

DealWithIt:
  Select Case position
    Case 0: GoTo EndOfLogic
    Case 1: GoTo Statement01
    Case 2: GoTo Statement02
    Case 3: GoTo Statement03
    Case 4: GoTo Statement04
  End Select
Catch
  GoTo DealWithIt
End Try
EndOfLogic:
End

The code depends heavily on the GoTo statement, using it to jump back into the action if an error ever does occur halfway through. It seems like a dramatic increase in code.

I'm not an expert in software benchmarking, but my guess is that the performance overhead inherent in repeatedly entering and exiting error handling blocks exceeds the extra time consumed by assigning the position variable over and over again. And if no exception is ever thrown, the entire DealWithIt block is passed over completely.

Which method should you use when replacing your unstructured error statements? It's difficult to answer without knowing the exact nature of your routine's logic. But if you have a secret desire to read through pages of assembly language-style code, using the output from the Visual Basic compiler isn't a bad place to start.

About the Author

Tim Patrick has spent more than thirty years as a software architect and developer. His two most recent books on .NET development -- Start-to-Finish Visual C# 2015, and Start-to-Finish Visual Basic 2015 -- are available from http://owanipress.com. He blogs regularly at http://wellreadman.com.

comments powered by Disqus
Upcoming Events

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.