Error Handling in VB.NET

Error handling is a crucial aspect of robust software development. It allows your application to gracefully manage unexpected situations, preventing crashes and providing a better user experience. Visual Basic .NET provides several mechanisms for handling errors.

The On Error Statement (Legacy)

While still supported for backward compatibility, the On Error statement is generally discouraged in modern VB.NET development in favor of structured exception handling.

Using On Error GoTo can make code harder to read and debug. Prefer Try...Catch...Finally blocks for better structured error management.

Here's how it works:


Sub ProcessFileLegacy(fileName As String)
    On Error GoTo ErrorHandler ' Enable error handling
    ' ... code that might cause an error ...
    Dim fileStream As System.IO.StreamReader = System.IO.File.OpenText(fileName)
    Dim content As String = fileStream.ReadToEnd()
    fileStream.Close()
    Console.WriteLine("File processed successfully.")
    Exit Sub ' Exit if no error occurred

ErrorHandler:
    ' Error handling code goes here
    Dim errorNumber As Integer = Err.Number
    Dim errorMessage As String = Err.Description
    Console.WriteLine($"An error occurred: {errorNumber} - {errorMessage}")
    ' You can also use Resume Next to continue execution after the error
    ' Resume Next
End Sub
            

The On Error statement has a few variations:

Structured Exception Handling (Try...Catch...Finally)

This is the recommended and modern approach to error handling in VB.NET. It provides a more structured and readable way to manage exceptions.

Keywords: Try, Catch, Finally, Throw, Exception

The Try Block

The code that might potentially raise an exception is placed within the Try block.

The Catch Block

If an exception occurs in the Try block, control is transferred to the appropriate Catch block. You can have multiple Catch blocks to handle different types of exceptions.


Public Function DivideNumbers(numerator As Double, denominator As Double) As Double
    Try
        If denominator = 0 Then
            ' Explicitly throw an exception
            Throw New ArgumentException("Denominator cannot be zero.")
        End If
        Return numerator / denominator
    Catch ex As DivideByZeroException
        Console.WriteLine($"Error: Cannot divide by zero. Details: {ex.Message}")
        Return Double.NaN ' Return Not-a-Number to indicate an invalid result
    Catch ex As ArgumentException
        Console.WriteLine($"Error: Invalid argument. Details: {ex.Message}")
        Return Double.NaN
    Catch ex As Exception
        ' Catch any other unhandled exceptions
        Console.WriteLine($"An unexpected error occurred: {ex.Message}")
        Return Double.NaN
    End Try
End Function
            

The Finally Block

The Finally block contains code that will execute regardless of whether an exception was thrown or caught. This is often used for cleanup operations, such as closing file handles or releasing resources.


Public Sub ProcessFileModern(fileName As String)
    Dim fileStream As System.IO.StreamReader = Nothing
    Try
        fileStream = System.IO.File.OpenText(fileName)
        Dim content As String = fileStream.ReadToEnd()
        Console.WriteLine("File content read.")
        ' ... further processing ...
    Catch ex As System.IO.FileNotFoundException
        Console.WriteLine($"Error: File not found. {ex.Message}")
    Catch ex As Exception
        Console.WriteLine($"An error occurred: {ex.Message}")
    Finally
        ' This block always executes
        If fileStream IsNot Nothing Then
            fileStream.Close()
            Console.WriteLine("File stream closed.")
        End If
    End Try
End Sub
            

The Throw Statement

You can use the Throw statement to explicitly raise an exception. This is useful when you detect a condition that your method cannot handle and want to signal the problem to the calling code.

When throwing an exception, consider creating custom exception types for more specific error reporting.

Exception Hierarchy

All exceptions in .NET inherit from the System.Exception class. Common exception types include:

Best Practices