VBUC Documentation | Mobilize.Net
Mobilize.NetForumsBlogDocumentation Home
  • Mobilize.Net VBUC
  • Introduction
  • Install and Licenses
  • Get Started
  • Migration Guide
  • VBUC Features
  • Mappings Grammar
  • Generated Code
  • Upgrade Options
    • Data Access
    • Grids
    • Microsoft
    • Sheridan
    • Others
    • Code Conversion
    • C# Features
  • Third-party controls
  • Best Practices
  • EWIs
    • Warnings
    • Issues
    • ToDos
    • Notes
  • Issues and Troubleshooting
    • Microsoft.VisualBasic Uses
    • Safe and Unsafe Methods Layer
    • Third Party Components
    • Migration Process
    • Classic ADO Conversion to ADO.NET
    • VB6 and .NET integer division
    • VB6 On Error Statements
    • Running a .NET Core application in a machine with no Visual Studio installed
    • Databases issues
    • Unsupported assemblies on .NET Core and .NET 5
    • Icon Extraction Issues
    • HTTPS sites are not loaded in Windows XP
    • Short-Circuit Boolean Logic in C#
    • Assessment Report Issue
  • Knowledge Base
    • FAQ
      • Does the VBUC support the Sheridan VB 6.0 controls suit?
      • How effective is the Visual Basic Upgrade Companion tool at converting an application's front end?
      • What controls does the Visual Basic Upgrade Companion tool supports?
      • How does the VBUC handle VB6 Collections?
      • Can the VBUC migrate intrinsic VB6 functions and libraries?
      • Where is the source code for the support (helper) classes used by the VBUC?
      • How does the VBUC convert ADO to ADO.NET?
      • Can the Visual Basic Upgrade Companion tool be customized?
      • What are Stubs?
    • How-To
      • App.Config and Database Access
      • Avoid reflection in Hot Paths
      • Convert ESRI ArcGIS Visual Basic 6.0 applications to .NET
      • Drag and Drop Conversion Steps
      • Inserting elements in a ListView
      • String vs StringBuilder
      • Word Automation in VB6 vs .NET
      • Configure default Factory Database provider
      • GetPrivateProfileString Windows API working in migrated code
      • Upgrade projects with shared files
  • Release Notes
Powered by GitBook
On this page
  • On-Error-GoTo label
  • On Error Resume Next

Was this helpful?

  1. Issues and Troubleshooting

VB6 On Error Statements

On-Error-GoTo label

Description

Error handling statements in VB6 rely on labels that can produce complex code. Because of this, there are cases where the VBUC cannot perform an appropriate transformation, so an EWI is generated. In those cases, manual changes must be made to fix the issue.

Alternative solution

Consider the following VB6 code:

Function Foo() As Boolean

    Dim objTest As Object
    Dim flag As Boolean

    On Local Error GoTo LabelError

    Set objTest = myWorkspace.CreateObject("MyObject")
    flag = True

    GoTo LabelExit

LabelError:

    flag = False
    MsgBox "Error"

LabelExit:

    Set objTest = Nothing

    Foo = flag
End Function

For that case, the On Local Error GoTo LabelError cannot be translated. The migrated version of the method would look like this:

public bool Foo()
{
    object objTest = null;
    bool flag = false;

    //UPGRADE_TODO: (1065) Error handling statement (On Error Goto) could not be converted. More Information: https://www.mobilize.net/vbtonet/ewis/ewi1065
    UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("On Error Goto Label (LabelError)");

    objTest = new MyObject();
    flag = true;

    goto LabelExit;

LabelError:

    flag = false;
    MessageBox.Show("Error");

LabelExit:

    objTest = null;

    return flag;
}

Most cases can be translated into a try-catch-finally statement. The following code shows an equivalent way to transform the original error pattern:

public bool Foo()
{
    object objTest = null;
    bool flag = false;

    try
    {
        objTest = new MyObject();
        flag = true;
    }
    catch (Exception ex)
    {
        flag = false;
        MessageBox.Show("Error");
    }
    finally
    {
        objTest = null;
    }

    return flag;
}

Notice the migrated code shows a pattern: the LabelError contains statements to take action when an error occurs (prone to be in a catch block) and the LabelExit contains statements that execute regardless of the error occurring or not (prone to be in a finally block). In those cases, a regular expression can be helpful to make a massive transformation of the migrated code. If you are not familiar with regular expressions, please read the following information.

The following is a possible regular expression that identifies the pattern:

(?^\s)(?UpgradeHelpers."On Error Goto Label (LabelError)")(?(.|\s|\n)?)(?LabelError:)(?(.|\s|\n)?)(?LabelExit:)(?(.|\s|\n)*?)(?(return))

The following is a possible replacement pattern for the regular expression indicated above:

{p1}try\n{\n{p3}\n}\ncatch(Exception exc)\n{\n{p5}\n\n}\nfinally\n{{p7}\n}\n${p8}

Using expressions like the ones shown above can transform the code automatically for those cases where the patterns appear en masse.

On Error Resume Next

Description

In .NET, the equivalent structured model for On Error Resume Next would be a Try-Catch for every single statement in the block where the "resume next" is active. Applying that kind of conversion would result in very low-quality code. Instead, it is recommended that the error-prone statements be manually identified and handled individually with a different model.

Example 1

VB6 code:

On Error Resume Next
<CodeBlock1>
If Err.Number <> 0 Then
<CodeBlock2>
End If 
Err.Clear

C# code:

try
{
<CodeBlock1>
}
catch
{
<CodeBlock2>
}

In this example, the programmer was expecting an error in CodeBlock1. If that happens, Err.Number is going to be a number different than 0, so the code flow will be entering the following if statement. The solution is to place CodeBlock1 in a try-catch and CodeBlock2 in the catch block.

Example 2

VB6 code:

On Error Resume Next
<CodeBlock1>
If Err.Number = SomeErrorCode Then
<CodeBlock2>
End If 
Err.Clear

C# code:

try
{
<CodeBlock1>
}
catch(SomeException e)
{
<CodeBlock2>
}

This is a small variation of the first example. What changes here is the programmer wanted to handle only a specific kind of error. Since Information.Err doesn't have the same behavior in .NET as in VB6, the solution is to find the corresponding exception to match the error code and catch it in the .NET migrated code.

Example 3

VB6 code:

On Error Goto errLabel
<CodeBlock1>
On Error Resume Next
<CodeBlock2>
If Err.Number <> 0 Then
<CodeBlock3>
End If 
On Error Goto errLabel
<CodeBlock4>
errlabel:
<CodeBlock5>

C# code:

try
{
<CodeBlock1>
  try
  {
  <CodeBlock2>
  }
  catch
  {
  <CodeBlock3>
  }
<CodeBlock4>
}
catch
{
<CodeBlock5>
}

This is a combination of error handling with On Error Goto Label and On Error Resume Next. If an error happens in CodeBlock1 or CodeBlock4 it should be handled with CodeBlock5, but if something happens in CodeBlock2 the error handling is executed by CodeBlock3. The solution here is to create a combination of try-catch that allows this execution flow.

Example 4

VB6 code:

On Error Resume Next
<CodeBlock1>

C# code:

<NonErrorExpectingBlock1>
try
{
<ErrorExpectingBlock2>
}
catch{}
<NonErrorExpectingBlock3>

This is probably the worst scenario you can find in error handling. Here, the VB6 programmer wanted every statement in CodeBlock1 to be executed, without caring about what happened in previous statements.

As we explain at the beginning of this section, the equivalent in .NET of CodeBlock1 will be a try-catch for every statement, but he is undesirable. For this case, the recommendation is to find every statement that could raise an error and put it within a try with an empty catch (if possible, you can create a better code that prevents the exceptions). There are many statements where you don't expect errors, such as variable assignments (i = 0), but you should consider a try-catch for statements that use COM objects or connections to databases.

PreviousVB6 and .NET integer divisionNextRunning a .NET Core application in a machine with no Visual Studio installed

Last updated 3 years ago

Was this helpful?