Library
Module
Module type
Parameter
Class
Class type
A trace
is a stack of error
s. It is implemented as an error list
but such a list MUST NEVER be empty.
It is implemented as a concrete error list
for backwards compatibility but future improvements might modify the type or render the type abstract.
include Sig.TRACE with type 'err trace = 'err list
trace
is abstract in this interface but it is made concrete in the instantiated error monad (see error_monad.mli
).
The idea of abstracting the trace is so that it can evolve more easily. Eventually, we can make the trace abstract in the instantiated error monad, we can have different notions of traces for the protocol and the shell, etc.
val make : 'error -> 'error trace
make e
makes a singleton trace, the simplest of traces that carries a single error.
cons e t
(construct sequential) constructs a sequential trace. This is for tracing events/failures/things that happen one after the other, generally one as a consequence of the other. E.g.,
let file_handle =
match attempt_open name with
| Ok handle -> Ok handle
| Error error ->
let trace = make error in
match attempt_create name with
| Ok handle -> Ok handle
| Error error -> Error (cons error trace)
When you are within the error monad itself, you should build traces using the record_trace
, trace
, record_trace_eval
and trace_eval
functions directly. You should rarely need to build traces manually using cons
. This here function can be useful in the case where you are at the interface of the error monad.
val cons_list : 'error -> 'error list -> 'error trace
cons_list error errors
is the sequential composition of all the errors passed as parameters. It is equivalent to folding cons
over List.rev error :: errors
but more efficient.
Note that error
and errors
are separated as parameters to enforce that empty traces cannot be constructed. The recommended use is:
match all_errors with
| [] -> Ok () (* or something else depending on the context *)
| error :: errors -> Error (cons_list error errors)
When you are within the error monad itself, you should build traces using the record_trace
, trace
, record_trace_eval
and trace_eval
functions directly. You should rarely need to build traces manually using cons_list
. This here function can be useful in the case where you are at the interface of the error monad.
conp t1 t2
(construct parallel) construct a parallel trace. This is for tracing events/failure/things that happen concurrently, in parallel, or simply independently of each other. E.g.,
let fetch_density () =
let area = fetch_area () in
let population = fetch_population () in
match area, population with
| Ok area, Ok population -> Ok (population / area)
| Error trace, Ok _ | Ok _, Error trace -> Error trace
| Error trace1, Error trace2 -> Error (conp trace1 trace2)
When you are within the error monad itself, you should rarely need to build traces manually using conp
. The result-concurrent traversors will return parallel traces when appropriate, and so will join_e
, join_ep
, both_e
, both_ep
, all_e
and all_ep
.
conp_list trace traces
is the parallel composition of all the traces passed as parameters. It is equivalent to List.fold_left conp trace traces
but more efficient.
Note that trace
and traces
are separated as parameters to enforce that empty traces cannot be constructed. The recommended use is:
match all_traces with
| [] -> Ok () (* or something else depending on the context *)
| trace :: traces -> Error (conp_list trace traces)
When you are within the error monad itself, you should rarely need to build traces manually using conp
. The result-concurrent traversors will return parallel traces when appropriate, and so will join_e
, join_ep
, both_e
, both_ep
, all_e
and all_ep
.
val pp_print :
(Format.formatter -> 'err -> unit) ->
Format.formatter ->
'err trace ->
unit
pp_print
pretty-prints a trace of errors
val pp_print_top :
(Format.formatter -> 'err -> unit) ->
Format.formatter ->
'err trace ->
unit
pp_print_top
pretty-prints the top errors of the trace
val encoding : 'error Data_encoding.t -> 'error trace Data_encoding.t
val fold : ('a -> 'error -> 'a) -> 'a -> 'error trace -> 'a
fold f init trace
traverses the trace (in an unspecified manner) so that init
is folded over each of the error within trace
by f
. Typical use is to find the worst error, to check for the presence of a given error, etc.