Category — .NET Framework Development
The Case of the Disappearing Exception
I was doing some debugging recently on an inherited Visual Basic.NET codebase. Something odd was going on – the code that reads a PLC’s input was always returning True, but I could see the input changing. The problem? The original programmer, who I’ll call “Bugs Bunny”, didn’t understand exception handling at all.
The function, part of a class that communicated with a PLC, went roughly like this:
Function bubba() As Boolean bubba = True Try bubba = getResultFromPlc() Catch ex As Exception logException() End Try End Function |
Since all Exceptions are caught and not handled any Exceptions raised in bubba()’s Try block just disappear. So all the code calling bubba() has no way of knowing if there are problem (such as the PLC isn’t powered or the serial port isn’t connected) . Instead, because the return value is initially set to True (bubba = True), if an Exception occurs, bubba() always return True.
Sometimes you do need to ignore Exceptions. For example, on a maintenance screen that repeatedly reads a PLC’s inputs, it’s good to indicate if there are any problems reading the inputs, but it’s not helpful to pop up a dialog box or exit the maintenance screen. Exceptions should be ignored occasionally as needed in the calling code, not completely swallowed up in the base library code.
Another common anti-pattern in Bug’s code is:
Sub joe() Try blah() blahblah() Catch ex As Exception logException() Throw ex End Try End Sub Sub groovy() Try joe() Catch ex As Exception logException() Throw ex End Try End Sub |
What’s the point? All that happens is the exception gets logged multiple times (adding confusion to the log file), more useless code is added (making the code harder to understand), and the program runs slower (throw, catching, and re-throwing Exceptions takes time).
Tony
June 24, 2008 2 Comments
Write Microsoft .NET code faster with Boo
even if you’re using C# or VB.NET. How? By using Boo’s interpreter to try out ideas, test usage of .NET framework functions, and interact with components (COM, .NET). Then when you’re comfortable, you can write the polished code in the language of your choice.
This is one use for mixed language programming, mentioned by me here, but where the final software might not use both languages.
In fact, any .NET interpreter such as IronPython or IronRuby could be used. And it’s a great technique for other than .NET – I’ve used it a lot with Python on Win32, and you can use it in Java with JRuby, Jython, Groovy, etc. This approach could be very useful for embedded and factory software development.
On .NET IronPython and IronRuby have advantages because they’re official Microsoft languages (and IP has a book coming out – IronPython In Action) and the languages are already in wide use (Win32, *nix, Java). I’m using Boo because it comes with the open source SharpDevelop IDE, and right now it integrates better with .NET (IP does not support attributes well, and it’s not easy to make an IP assembly callable by other .NET languages, etc).
Short example – interactively using DirectoryInfo in Boo (text I typed in bold):
>>> di = DirectoryInfo(“C:\\Download”)
C:\Download
>>> files = di.GetFiles()
(AdbeRdr80_en_US.exe, AdbeRdr80_en_US_Nosso_error.log, Firefox Setup 2.0.0.1.exe, SharpDevelop_2.2.1.2648_Setup.msi, TortoiseSVN-1.4.3.8645-win32-svn-1.4.3.msi)
>>> files = di.GetFiles(‘t*’)
(TortoiseSVN-1.4.3.8645-win32-svn-1.4.3.msi)
Interactively calling a COM object in Boo:
>>> ieType = System.Type.GetTypeFromProgID(‘InternetExplorer.Application’)
System.__ComObject
>>> ie = System.Activator.CreateInstance(ieType)
System.__ComObject
>>> ie.Visible
false
>>> ie.Visible = true
true
>>> ie.Visible
true
So far I haven’t had to use InvokeMember to call COM functions. At least for C# and VB.NET (and probably Boo) it appears you need to use it if you are using late binding. BTW, it is possible to use late binding with COM events, but it is significant extra work.
Tony
September 26, 2007 No Comments