Exceptions
Keeps the success branch out of the try scope (preserves tail calls).
17.1 Built-in exceptions
List.find, Hashtbl.find, String.index Invalid_argument of string bad args, out-of-bounds Failure of string failwith, int_of_string Sys_error of string OS-level file errors free for you to use Stack_overflow, Out_of_memory assert false non-exhaustive match at runtime
17.2 Raising
failwith "something went wrong" (* raise (Failure "...") *)
invalid_arg "negative input" (* raise (Invalid_argument "...") *)
raise Not_found
assert (x >= 0)17.3 Defining exceptions
exception Insufficient_funds of float
exception Parse_error of { line : int; msg : string }17.4 Handling
let safe_div a b =
try a / b with
| Division_by_zero -> 0
let withdraw balance amount =
if amount > balance then raise (Insufficient_funds (amount -. balance))
else balance -. amount
let () =
try ignore (withdraw 100. 150.) with
| Insufficient_funds short -> Printf.printf "Short by %.2f\n" short
| e -> Printf.printf "Other: %s\n" (Printexc.to_string e)17.5 Exceptions in match
Keeps the success branch out of the try scope (preserves tail calls).
match List.assoc key table with
| v -> use v
| exception Not_found -> default17.6 Cleanup: Fun.protect
Also In_channel.with_open_text (see §19).
let with_file path f =
let ic = open_in path in
Fun.protect ~finally:(fun () -> close_in ic) (fun () -> f ic)17.7 Backtraces
let () = Printexc.record_backtrace true
(* or env var OCAMLRUNPARAM=b *)
try risky () with e ->
prerr_endline (Printexc.to_string e);
Printexc.print_backtrace stderr;
raise e (* or Printexc.raise_with_backtrace e bt *)17.8 Using exceptions for early exit
let find_index p arr =
let exception Found of int in (* local exception *)
try
Array.iteri (fun i x -> if p x then raise (Found i)) arr; None
with Found i -> Some i