CodeSOD: On Error Goto Anywhere but Here

One of the big pieces of advice about using exceptions and errors is that they shouldn't be used for flow control. You catch an exception when an exceptional event happens, but you don't, for example, throw an exception to break out of a loop.

Unless you're Python, which throws exceptions to break out of loops. That's just how iteration works. But we're not here to talk about Python.

If a sufficiently motivated programmer can write LISP in any language, today's code, found by Maxi attempts to write Python in VB.Net. This snippet represents a general pattern around fetching data from temporary files.

DIM Buffer(5000) AS STRING DIM Index AS INTEGER ON ERROR RESUME NEXT ERN=0 Index=0 WHILE ERN<>0 IF(Buffer(Index)="") THEN ENDIF REM ...Do something... Index=Index+1 WEND

Here, we see the venerable VisualBasic On Error Resume Next. Before VB.Net, Visual Basic didn't have structured exception handling. You have a few options in pre-.NET Visual Basic for how to handle errors, but On Error Resume Next says "ignore errors, and I'll check to see if there's an error by examining the global variable Err.

Which, you'll note, Err is not ERN. Hidden behind the Do something comment, this code will perform an action which might fail, and set ERN = Err.Number- sometimes. It may also just set ERN itself, when it decides the loop is over. Sometimes this pattern is used to create retry blocks, where they only set ERN when the process succeeds.

Now, in this specific example, there's an additional factor. The Buffer is declared as an array of 5000 elements. So that seemingly do-nothing IF statement actually is vital: in ensures that once we cross 5000 iterations, it ensures that an error happens.

Every method uses On Error Resume Next, and pretty much every loop is written using this pattern. And honestly, that might not even be the worst of it. This is how they construct SQL statements, and what you're about to see is not anonymized or altered:

Sql="SELECT * FROM TableTemp WHERE xyz='"+Xyz+''"

Yes, the table name is actually TableTemp, yes the column is actually xyz, as in the SQL-injection-friendly variable.

Maxi is, slowly but surely, rolling a boulder up the hill, and promises that the code "is getting better". I fear that's a very tall hill.

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!

This post originally appeared on The Daily WTF.

Leave a Reply

Your email address will not be published.