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.
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:
On Error GoTo label
: Transfers control to the specified label when an error occurs.On Error Resume Next
: Continues execution with the statement immediately following the one that caused the error.On Error GoTo 0
: Disables error handling.
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.
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.
Exception Hierarchy
All exceptions in .NET inherit from the System.Exception
class. Common exception types include:
ArgumentException
: Thrown when a method receives an argument that is not valid.DivideByZeroException
: Thrown when the denominator of a division operation is zero.FileNotFoundException
: Thrown when an attempt to access a file that does not exist fails.NullReferenceException
: Thrown when the result of an expression that dereferences a null reference is used.IndexOutOfRangeException
: Thrown when the index of an array element is outside the bounds of the array.
Best Practices
- Use
Try...Catch...Finally
for structured error handling. - Catch specific exceptions whenever possible.
- Avoid catching the generic
Exception
unless it's the last resort. - Use the
Finally
block for resource cleanup. - Provide informative error messages.
- Consider logging errors for debugging and auditing.