> For the complete documentation index, see [llms.txt](https://docs.gapvelocity.ai/vbuc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.gapvelocity.ai/vbuc/issues-troubleshooting/vb6-on-error-statements.md).

# 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 VB6 AI Migrator 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:

```php
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:

```csharp
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:

```csharp
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:*

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

*C# code:*

```csharp
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:*

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

*C# code:*

```csharp
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:*

```php
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:*

```csharp
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:*

```php
On Error Resume Next
<CodeBlock1>
```

*C# code:*

```csharp
<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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.gapvelocity.ai/vbuc/issues-troubleshooting/vb6-on-error-statements.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
