tezos-error-monad
  1. Overview
  2. Docs

Tezos Protocol Implementation - Error Monad

type error_category = [
  1. | `Branch
    (*

    Errors that may not happen in another context

    *)
  2. | `Temporary
    (*

    Errors that may not happen in a later context

    *)
  3. | `Permanent
    (*

    Errors that will happen no matter the context

    *)
]

Categories of error

include Sig.CORE
type error = ..
val error_encoding : error Data_encoding.t
val pp : Format.formatter -> error -> unit
val register_error_kind : Sig.error_category -> id:string -> title:string -> description:string -> ?pp:(Format.formatter -> 'err -> unit) -> 'err Data_encoding.t -> (error -> 'err option) -> ('err -> error) -> unit

The error data type is extensible. Each module can register specialized error serializers id unique name of this error. Ex.: overflow_time_counter title more readable name. Ex.: Overflow of time counter description human readable description. Ex.: The time counter overflowed while computing delta increase pp formatter used to pretty print additional arguments. Ex.: The time counter overflowed while computing delta increase. Previous value %d. Delta: %d encoder decoder data encoding for this error. If the error has no value, specify Data_encoding.empty

val classify_error : error -> Sig.error_category

Classify an error using the registered kinds

include Sig.EXT with type error := error
type error +=
  1. | Unclassified of string
    (*

    Catch all error when 'deserializing' an error.

    *)

Catch all error when 'serializing' an error.

type error +=
  1. | Unregistred_error of Data_encoding.json
val json_of_error : error -> Data_encoding.json

An error serializer

val error_of_json : Data_encoding.json -> error

Error documentation

type error_info = {
  1. category : Sig.error_category;
  2. id : string;
  3. title : string;
  4. description : string;
  5. schema : Data_encoding.json_schema;
}

Error information

val pp_info : Format.formatter -> error_info -> unit
val get_registered_errors : unit -> error_info list

Retrieves information of registered errors

include Sig.WITH_WRAPPED with type error := error
module type Wrapped_error_monad = sig ... end
val register_wrapped_error_kind : (module Wrapped_error_monad) -> id:string -> title:string -> description:string -> unit
include Sig.MONAD with type error := error
type trace = error list

A trace is a stack of errors. 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.

val pp_print_error : Format.formatter -> trace -> unit
val trace_encoding : trace Data_encoding.t
val classify_errors : trace -> Sig.error_category
type 'a tzresult = ('a, trace) result

The error monad wrapper type, the error case holds a stack of error, initialized by the first call to fail and completed by each call to trace as the stack is rewinded. The most general error is thus at the top of the error stack, going down to the specific error that actually caused the failure.

val result_encoding : 'a Data_encoding.t -> 'a tzresult Data_encoding.t

A serializer for result of a given type

val ok : 'a -> 'a tzresult

Sucessful result

val return : 'a -> 'a tzresult Lwt.t

Sucessful return

val return_unit : unit tzresult Lwt.t

Sucessful return of ()

val return_none : 'a option tzresult Lwt.t

Sucessful return of None

val return_some : 'a -> 'a option tzresult Lwt.t

return_some x is a sucessful return of Some x

val return_nil : 'a list tzresult Lwt.t

Sucessful return of []

val return_true : bool tzresult Lwt.t

Sucessful return of true

val return_false : bool tzresult Lwt.t

Sucessful return of false

val error : error -> 'a tzresult

Erroneous result

val fail : error -> 'a tzresult Lwt.t

Erroneous return

val (>>?) : 'a tzresult -> ('a -> 'b tzresult) -> 'b tzresult

Non-Lwt bind operator

val (>>=?) : 'a tzresult Lwt.t -> ('a -> 'b tzresult Lwt.t) -> 'b tzresult Lwt.t

Bind operator

val (>>=) : 'a Lwt.t -> ('a -> 'b Lwt.t) -> 'b Lwt.t

Lwt's bind reexported

val (>|=) : 'a Lwt.t -> ('a -> 'b) -> 'b Lwt.t
val (>>|?) : 'a tzresult Lwt.t -> ('a -> 'b) -> 'b tzresult Lwt.t

To operator

val (>|?) : 'a tzresult -> ('a -> 'b) -> 'b tzresult

Non-Lwt to operator

val record_trace : error -> 'a tzresult -> 'a tzresult

Enrich an error report (or do nothing on a successful result) manually

val trace : error -> 'b tzresult Lwt.t -> 'b tzresult Lwt.t

Automatically enrich error reporting on stack rewind

val record_trace_eval : (unit -> error tzresult) -> 'a tzresult -> 'a tzresult

Same as record_trace, for unevaluated error

val trace_eval : (unit -> error tzresult Lwt.t) -> 'b tzresult Lwt.t -> 'b tzresult Lwt.t

Same as trace, for unevaluated Lwt error

val fail_unless : bool -> error -> unit tzresult Lwt.t

Erroneous return on failed assertion

val fail_when : bool -> error -> unit tzresult Lwt.t
val unless : bool -> (unit -> unit tzresult Lwt.t) -> unit tzresult Lwt.t
val _when : bool -> (unit -> unit tzresult Lwt.t) -> unit tzresult Lwt.t
val _assert : bool -> string -> ('a, Format.formatter, unit, unit tzresult Lwt.t) format4 -> 'a

In-monad list iterators

val iter_s : ('a -> unit tzresult Lwt.t) -> 'a list -> unit tzresult Lwt.t

A List.iter in the monad

val iter_p : ('a -> unit tzresult Lwt.t) -> 'a list -> unit tzresult Lwt.t
val iteri_p : (int -> 'a -> unit tzresult Lwt.t) -> 'a list -> unit tzresult Lwt.t
val iter2_p : ('a -> 'b -> unit tzresult Lwt.t) -> 'a list -> 'b list -> unit tzresult Lwt.t
val iteri2_p : (int -> 'a -> 'b -> unit tzresult Lwt.t) -> 'a list -> 'b list -> unit tzresult Lwt.t
val map_s : ('a -> 'b tzresult Lwt.t) -> 'a list -> 'b list tzresult Lwt.t

A List.map in the monad

val rev_map_s : ('a -> 'b tzresult Lwt.t) -> 'a list -> 'b list tzresult Lwt.t
val map_p : ('a -> 'b tzresult Lwt.t) -> 'a list -> 'b list tzresult Lwt.t
val mapi_s : (int -> 'a -> 'b tzresult Lwt.t) -> 'a list -> 'b list tzresult Lwt.t
val mapi_p : (int -> 'a -> 'b tzresult Lwt.t) -> 'a list -> 'b list tzresult Lwt.t
val map2 : ('a -> 'b -> 'c tzresult) -> 'a list -> 'b list -> 'c list tzresult

A List.map2 in the monad

val map2_s : ('a -> 'b -> 'c tzresult Lwt.t) -> 'a list -> 'b list -> 'c list tzresult Lwt.t
val mapi2_s : (int -> 'a -> 'b -> 'c tzresult Lwt.t) -> 'a list -> 'b list -> 'c list tzresult Lwt.t
val filter_map_s : ('a -> 'b option tzresult Lwt.t) -> 'a list -> 'b list tzresult Lwt.t

A List.filter_map in the monad

val filter_map_p : ('a -> 'b option tzresult Lwt.t) -> 'a list -> 'b list tzresult Lwt.t
val filter_s : ('a -> bool tzresult Lwt.t) -> 'a list -> 'a list tzresult Lwt.t

A List.filter in the monad

val filter_p : ('a -> bool tzresult Lwt.t) -> 'a list -> 'a list tzresult Lwt.t
val fold_left_s : ('a -> 'b -> 'a tzresult Lwt.t) -> 'a -> 'b list -> 'a tzresult Lwt.t

A List.fold_left in the monad

val fold_right_s : ('a -> 'b -> 'b tzresult Lwt.t) -> 'a list -> 'b -> 'b tzresult Lwt.t

A List.fold_right in the monad

val join : unit tzresult Lwt.t list -> unit tzresult Lwt.t

A Lwt.join in the monad

val generic_error : ('a, Format.formatter, unit, 'b tzresult) format4 -> 'a

Erroneous result (shortcut for generic errors)

val failwith : ('a, Format.formatter, unit, 'b tzresult Lwt.t) format4 -> 'a

Erroneous return (shortcut for generic errors)

val error_exn : exn -> 'a tzresult
val record_trace_exn : exn -> 'a tzresult -> 'a tzresult
val trace_exn : exn -> 'b tzresult Lwt.t -> 'b tzresult Lwt.t
val generic_trace : ('a, Format.formatter, unit, ('b, trace) result Lwt.t -> ('b, trace) result Lwt.t) format4 -> 'a
val pp_exn : Format.formatter -> exn -> unit
val failure : ('a, Format.formatter, unit, error) format4 -> 'a
type error +=
  1. | Exn of exn

Wrapped OCaml/Lwt exception

type error +=
  1. | Canceled
val protect : ?on_error:(trace -> 'a tzresult Lwt.t) -> ?canceler:Lwt_canceler.t -> (unit -> 'a tzresult Lwt.t) -> 'a tzresult Lwt.t

protect is a wrapper around Lwt.catch where the error handler operates over `trace` instead of `exn`. Besides, protect ~on_error ~canceler ~f may *cancel* f via a Lwt_canceler.t.

More precisely, protect ~on_error ~canceler f runs f (). An Lwt failure triggered by f () is wrapped into an Exn. If a canceler is given and Lwt_canceler.cancellation canceler is determined before f (), a Canceled error is returned.

Errors are caught by ~on_error (if given), otherwise the previous value is returned. An Lwt failure triggered by ~on_error is wrapped into an Exn

type error +=
  1. | Timeout
val with_timeout : ?canceler:Lwt_canceler.t -> unit Lwt.t -> (Lwt_canceler.t -> 'a tzresult Lwt.t) -> 'a tzresult Lwt.t
module Make (Prefix : Sig.PREFIX) : sig ... end