Exceptions and Robust Error Handling

16.1 Try/Catch/Finally with Filters

Try
    ProcessFile(path)
Catch ex As FileNotFoundException
    _logger.LogWarning("Missing file {Path}", path)
Catch ex As IOException When IsTransient(ex)          ' exception filter: doesn't unwind the stack if False
    Retry()
Catch ex As Exception
    _logger.LogError(ex, "Unexpected failure")
    Throw                                              ' preserve the stack trace
Finally
    Cleanup()
End Try

16.2 Exception Design

Throw specific BCL exceptions: ArgumentException, ArgumentNullException (ArgumentNullException.ThrowIfNull(x)), ArgumentOutOfRangeException, InvalidOperationException, NotSupportedException, ObjectDisposedException, TimeoutException.

Custom exceptions: inherit Exception, provide the standard constructors, and add context properties. Wrap lower-level exceptions as InnerException.

Don't use exceptions for control flow. Use TryX patterns or Result(Of T) (Module 15) for expected failures.

Never swallow exceptions silently. Log with context. Fail fast on programming errors.

16.3 Global Handling

AddHandler AppDomain.CurrentDomain.UnhandledException,
    Sub(s, e) Log(CType(e.ExceptionObject, Exception))
AddHandler TaskScheduler.UnobservedTaskException,
    Sub(s, e) : Log(e.Exception) : e.SetObserved() : End Sub
' WinForms: Application.SetUnhandledExceptionMode + Application.ThreadException
' VB Application Framework: My.Application.UnhandledException in ApplicationEvents.vb
' WPF: Application.DispatcherUnhandledException

16.4 Resilience

Retry with exponential backoff, circuit breakers, and timeouts using Polly / Microsoft.Extensions.Resilience. Idempotent operations. Compensating actions.

Legacy On Error GoTo/Resume exists for VB6 compatibility. Don't use it in new code.