Error Handling and Exceptions
15.1 Structured Exception Handling (Try...Catch...Finally)
Order Catch blocks from the most specific to the most general.
Throw alone rethrows the current exception. Throw ex resets the stack trace (avoid it).
Exit Try leaves the Try block (the Finally block still runs).
Try
Dim n = Integer.Parse(input)
Dim result = 100 \ n
Console.WriteLine(result)
Catch ex As FormatException
Console.WriteLine("Not a valid number.")
Catch ex As DivideByZeroException
Console.WriteLine("Cannot divide by zero.")
Catch ex As Exception When ex.Message.Contains("timeout") ' exception filter (When)
Console.WriteLine("Timeout occurred.")
Catch ex As Exception
Console.WriteLine($"Unexpected error: {ex.Message}")
Throw ' rethrow, preserving the stack trace
Finally
Console.WriteLine("Cleanup always runs.")
End Try15.2 Common Exception Types
Accessing a member on Nothing Bad conversion/cast Numeric overflow (checked by default in VB!) Integer division by zero
IndexOutOfRangeException / ArgumentOutOfRangeException ArgumentException / ArgumentNullException Invalid object state Missing dictionary key
FileNotFoundException / IOException / UnauthorizedAccessException
NotImplementedException / NotSupportedException TimeoutException, HttpRequestException, SqlException
VB checks integer overflow by default (C# doesn't). You can disable this with the project setting *Remove integer overflow checks* (<RemoveIntegerChecks>true</RemoveIntegerChecks>).
15.3 Throwing and Custom Exceptions
Public Class InsufficientFundsException
Inherits Exception
Public ReadOnly Property Shortfall As Decimal
Public Sub New(message As String, shortfall As Decimal)
MyBase.New(message)
Me.Shortfall = shortfall
End Sub
Public Sub New(message As String, inner As Exception)
MyBase.New(message, inner)
End Sub
End Class
Sub Withdraw(amount As Decimal)
If amount <= 0 Then Throw New ArgumentOutOfRangeException(NameOf(amount), "Must be positive.")
If amount > Balance Then Throw New InsufficientFundsException("Insufficient funds", amount - Balance)
Balance -= amount
End Sub15.4 Exception Properties
ex.Message, ex.StackTrace, ex.InnerException, ex.Source, ex.GetType().Name, ex.Data, ex.ToString() (full details), and ex.GetBaseException().
15.5 Unstructured Error Handling (Legacy: On Error)
You can't mix On Error and Try...Catch in the same procedure. Use Try...Catch in VB.NET.
Sub LegacyStyle()
On Error GoTo ErrorHandler
Dim x = 1 \ 0
Exit Sub
ErrorHandler:
Console.WriteLine($"Error {Err.Number}: {Err.Description}")
Resume Next ' continue with the next statement (dangerous)
End Sub
' On Error Resume Next ignores errors entirely. Avoid it in VB.NET (it's common in VBA/VB6).15.6 Exception Handling Best Practices
Catch only what you can handle. Don't swallow exceptions silently.
Use TryParse / TryGetValue instead of exceptions for expected situations.
Use Using for resources (Module 24). Log exceptions with context.
Global handlers: AppDomain.CurrentDomain.UnhandledException, Application.ThreadException (WinForms), My.Application.UnhandledException (VB Application Framework), TaskScheduler.UnobservedTaskException.