An exception is a runtime event for an abnormal condition. In .NET, throwing one stops normal execution and unwinds the call stack until code catches it or the application ends. section 9.2.4
F# handles exceptions with try/with. Catch an exception locally when recovery is possible; otherwise let it bubble upward. An uncaught exception commonly becomes an HTTP 500 in a web application or stops a console or desktop program. section 9.2.4
Catch a failed division
try Some (1 / 0) with ex -> printfn $"Error: {ex.Message}" None For reusable boundaries, wrap any function so success becomes Ok and failure becomes Error ex. Partially applying the wrapper creates a safe version such as divideSafe.
Prefer explicit return types for expected outcomes, and reserve exceptions for failures that should stop normal processing:
- Use options when data may be absent. section 9.2.6
- Use results when callers need to reason about success or a specific error. section 9.2.6
- Use exceptions for panic situations and fail-fast paths, not regular control flow. section 9.2.6
- Watch for unsafe collection functions, array indexing, division by zero, and external libraries; choose runtime-safe alternatives where available. section 9.2.4
Figure 9.4 Options and results are normal return values of functions, whereas an exception can implicitly bubble all the way up the call stack until it encounters a try/with block.
Compare explicit Option and Result return values with exceptions that implicitly travel up the call stack until try/with handles them. section 9.2.6
























