The latest release of the Visual Basic Upgrade Companion improves the support for moving from VB6.0's On Error Statements to C# structured error handling, using try/catch blocks. In this post I will cover a couple of examples on how this transformation is performed.
First of, this is something that you may not need/want in your application, so this is a features managed through the Migration Profile of the application. In order to enable it, in the Profile, make sure the "On Error To Try Catch" feature is enabled.
Now let's get started with the examples.
On Error Resume Next
First of, let's cover one of the most frustrating statements to migrate from VB6.0: the dreaded On Error Resume Next. This statement tells VB6.0 to basically ignore errors and continue execution no matter what. VB6.0 can recover from some errors, so an application can continue without being affected. These same errors, however, can cause an exception in .NET, or may leave the application in an inconsistent state.
Now let's look at a code example in VB6.0:
Private Sub bttnOK_Click()
On Error Resume Next
MsgBox ("Assume this line throws an error")
End Sub
The VBUC would then leave it as follows in C#:
private void bttnOK_Click( Object eventSender, EventArgs eventArgs)
{
//UPGRADE_TODO: (1069) Error handling statement
(On Error Resume Next) was converted to a complex pattern which
might not be equivalent to the original.
try
{
MessageBox.Show("Assume this line throws an error",
Application.ProductName);
}
catch (Exception exc)
{
throw new Exception(
"Migration Exception: The
following exception could be handled in a different
way after the conversion: " + exc.Message);
}
}
Because of this, the decision was made to wrap the code that is in the scope of the On Error Resume Next statement on a try/catch block. This is likely the way it would be implement in a "native" .NET way, as there is no real equivalent functionality to tell C# to ignore errors and continue. Also, the VBUC adds a comment (an UPGRADE_TODO), so the developer can review the scenario and make a judgement call on wether to leave it as it is, or change it in some way. Most of the time, the try/catch block can be limited to just one line of code, but that modification requires some manual intervention. Still, it is easier when there is something already there.
:-)
On Error GoTo <label>
The other common scenario is to have a more structured approach to error handling. This can be illustrated with the following code snippet:
Private Sub bttnCancel_Click()
On Error GoTo errorHandler
MsgBox ("Assume this line throws an error")
exitSub:
Exit Sub
errorHandler:
MsgBox ("An error was caught")
GoTo exitSub
End Sub
Since this code is using a pattern that is very similar to what the try/catch statement would do, the VBUC is able to identify the pattern and move it to the appropriate try/catch block:
private void bttnCancel_Click( Object eventSender, EventArgs eventArgs)
{
try
{
MessageBox.Show("Assume this line throws an error", Application.ProductName);
}
catch
{
MessageBox.Show("An error was caught", Application.ProductName);
}
}
As you can see, the functionality of this type of pattern is replicated completely, maintaining complete functional equivalence with the VB6.0 code.
Overall, the support for converting On Error statements from VB6.0 into the proper structured error handling structures in C# has come a long way. It is now very robust and supports the most commonly used patterns. So, unless you are using some strange spaghetti code or have a very peculiar way of doing things, the VBUC will be able to translate most scenarios without issues. Some of them, as mentioned, may still required human intervention, but let's face it - using On Error Resume Next shouldn't really be allowed in any programming language!! ;-)