Line numbers have been around ever since the dawn of time in BASIC.
Remember this classic:
10 Print “Hello”
20 Goto 10
But what many people may not know is that line numbers still exist in VB.Net!
Yep, that’s right, you can write the above routine, as I show it, in VB.NET.
Well, with one exception. Line numbers in .NET are treated as full on labels, and labels must be followed by a colon. So you’d have this in .NET:
10: Print “Hello”
20: Goto 10
Now, before I start getting hate mail about GOTO’s and such, let me say that I’m only a fan of a GOTO in a few very controlled circumstances.
But GOTO’s are the point here. Way back in the Visual Basic (Pre .NET days), line numbers combined with the ERL function made for a surprisingly effective field debugging tool. If you line numbered your code before compiling, and used ERL appropriately during your error handling, you’d be able to precisely pinpoint the offending line of code very quickly and painlessly.
I’ve used that approach for years, and even wrote an article in VB Programmers journal at one point about a very extensive generic error handling facility.
Recently, I decided to look into updating that facility for VB.NET, and unfortunately have good and bad things to report.
First the good.
- As I said before, VB.NET still supports line numbers and the ERL statement, as well as all the old favorites ON ERROR RESUME NEXT, ON ERROR GOTO, RESUME, and RESUME NEXT.
- You can easily compile VB.NET projects from the command line, making it relatively trivial to create a simple batch file to line number your code, compile it, then clean up the line numbered version.
- VB.NET supports a much more sophisticated StackTrace/StackFrame functionallity that would seem, at first glance to obviate the need for ERL entirely.
but now the bad…
- The StackTrace/StackFrame functionality works fantastically, as long as you’re willing to ship the program debugging database (PDB files) that are generated when you compile your project.
- Worse still, you can’t use the old style ON ERROR GOTO, in the same method as the new style TRY CATCH FINALLY exception handling.
- And finally, the ultimate bit of nastiness. While trapping an error with the old style ON ERROR GOTO will generate a standard exception (See the Err.GetException method), trapping an exception with structured exception handling (also known as SEH, or TRY CATCH), does not affect the ERR object at all, specifically, throwing an error in a TRY block will not set the ERL value, even if the code is line numbered.
So what’s the end result of all this?
Basically, do not even bother with ON ERROR GOTO style error handling in VB.Net. Even though it would appear to be supported, and even though retrieving the line number of the failing code isn’t possible without shipping your PDB, the fact that line numbers aren’t reported in code using SEH makes them pretty much useless. SEH is quite useful in many situations, so you wouldn’t want to not use it solely because of this.
But that doesn’t address two very real issues.
- Line numbers in stack traces are an incredibly useful debugging tool
- You don’t want to distribute your PDBs just to get line numbered stack traces if at all possible.
More to ponder…