- Use `Try`/`Catch`/`Finally` for all error handling — never use `On Error GoTo` or `On Error Resume Next` in new VB.NET code.
- Catch specific exception types rather than the bare `Exception` class: `Catch ex As SqlException`, `Catch ex As HttpRequestException` — broad catches hide bugs.
- Use `Finally` to release unmanaged resources or complete cleanup regardless of whether an exception occurred — or use `Using` blocks for `IDisposable` objects.
- Re-throw exceptions with `Throw` (not `Throw ex`) to preserve the original stack trace — `Throw ex` resets the stack trace and loses the failure origin.
- Create custom exception classes for domain-specific errors: `Class OrderNotFoundException : Inherits Exception` with meaningful messages and data properties.
- Wrap exceptions with contextual information: `Throw New ApplicationException($"Failed to process order {orderId}", ex)` to preserve the inner exception.
- Log exceptions at the boundary where they are caught and handled — avoid logging at every catch site to prevent duplicate log entries.