File: exn.md

package info (click to toggle)
ocaml-eio 1.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,548 kB
  • sloc: ml: 14,608; ansic: 1,237; makefile: 25
file content (85 lines) | stat: -rw-r--r-- 2,046 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# Setting up the environment

```ocaml
# #require "eio.mock";;
```

Adjust this to test backtrace printing:
```ocaml
let () = Printexc.record_backtrace false
```

```ocaml
let non_io a =
  try failwith a
  with ex -> ex, Printexc.get_raw_backtrace ()

let not_found =
  try raise @@ Eio.Fs.err (Not_found Eio_mock.Simulated_failure)
  with ex ->
    let bt = Printexc.get_raw_backtrace () in
    let ex = Eio.Exn.add_context ex "opening file 'foo'" in
    ex, bt

let denied =
  try raise @@ Eio.Fs.err (Permission_denied Eio_mock.Simulated_failure)
  with ex ->
    let bt = Printexc.get_raw_backtrace () in
    let ex = Eio.Exn.add_context ex "saving file 'bar'" in
    ex, bt

let combine a b =
  fst @@ Eio.Exn.combine a b
```

## Combining exceptions

Combining regular exceptions:

```ocaml
# raise @@ combine (non_io "a") (non_io "b");;
Exception: Multiple exceptions:
- Failure("a")
- Failure("b")
```

An IO error and a regular exception becomes a regular (non-IO) multiple exception:

```ocaml
# raise @@ combine (non_io "a") not_found;;
Exception:
Multiple exceptions:
- Failure("a")
- Eio.Io Fs Not_found Simulated_failure,
    opening file 'foo'
```

Combining IO exceptions produces another IO exception,
so that if you want to e.g. log all IO errors and continue then that still works:

```ocaml
# Fmt.pr "%a@." Eio.Exn.pp (combine denied not_found);;
Eio.Io Multiple_io
- Fs Permission_denied Simulated_failure, saving file 'bar'
- Fs Not_found Simulated_failure, opening file 'foo'
- : unit = ()
```

They form a tree, because the context information may be useful too:

```ocaml
let combined =
  let e = Eio.Exn.combine denied not_found in
  let ex = Eio.Exn.add_context (fst e) "processing request" in
  ex, snd e
```

```ocaml
# Fmt.pr "%a@." Eio.Exn.pp (combine combined not_found);;
Eio.Io Multiple_io
- Multiple_io
  - Fs Permission_denied Simulated_failure, saving file 'bar'
  - Fs Not_found Simulated_failure, opening file 'foo', processing request
- Fs Not_found Simulated_failure, opening file 'foo'
- : unit = ()
```