[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MirageOS-devel] Error handling in Mirage - request for comments!

On 3 February 2015 at 18:30, Ashish Agarwal <agarwal1975@xxxxxxxxx> wrote:
>> System 3 provides (I think) no easy way to match on the type of error.
> You can. An Error.t is constructed by using Sexplib. Thus, you can
> deserialize them to whatever specific error you want to consider. Here's an
> example:
> open Core.Std;;
> type myerr = [`Zero | `Neg of int] with sexp;;
> (* Get back to myerr if possible. *)
> let myerr_of_error (e:Error.t) : myerr option =
>   match Error.sexp_of_t e with
>   | Sexp.List (_::x::[]) -> Some (myerr_of_sexp x)
>   | _ -> None

I don't understand how this works. How does myerr_of_error know that
this is a myerr? It seems to be just testing that the sexp is a 2-item
list. Does it throw an exception if given some different type of

> let f x : int Or_error.t =
>   if x = 0 then error "zero not allowed" `Zero sexp_of_error
>   else if x < 0 then error "negative not allowed" (`Neg x) sexp_of_error
>   else Ok x
> ;;
> let g x = match f x with
> | Ok x -> x*x
> | Error e -> match myerr_of_error e with
>   | Some `Zero -> 0
>   | Some (`Neg x) -> x*x
>   | None -> 0 (* or parse e as another error type *)
> ;;
> In the last None clause above, you could try to parse e as another error
> type, continuing to consider as many error types as you want. The nice thing
> about this is you only have one error type, Error.t, so your APIs remain
> uncluttered. But you can deserialize to more strongly typed error types when
> you want to.
> The bad thing is the compiler can't tell you what are all the errors you
> have to consider, but this isn't achieved my most error handling strategies.
> Furthermore, this is all about errors, so I'm not sure exhaustiveness is so
> important.


>> Sometimes it's useful to organise errors into a hierarchy ... I don't see
>> any way to do this in OCaml.
> You can get this with polymorphic variants, e.g
> type tcp_connection_refused = [`TCP_connection_refused]
> type tcp_error = [tcp_connection_refused | `Another_err]

The problem is that the subclasses get added elsewhere. e.g.

mirage-types's FS may define Read_only, but an ext4 filesystem might
define e.g. Read_only_file, Immutable_file and FS_mounted_read_only.
Ideally, generic code catching Is_read_only should also catch the
specific cases.

In Java, you'd do something like:

  class Read_only extends Exception

Generic code would use "catch (Read_only ex)", but implementations
could also add subexceptions with:

  class FS_mounted_read_only extends Read_only_file

Code could then also catch this specific case if desired. More
importantly, though, the subexception can add extra details to the
error message.

> On Tue, Feb 3, 2015 at 12:26 PM, Sebastien Mondet
> <sebastien.mondet@xxxxxxxxx> wrote:
>> Yes if we just all agree on this type:
>> http://erratique.ch/software/fut/doc/Fut.html#TYPEresult
>> then we are all compatible without actual library dependencies, thanks to
>> structural typing
>> I've been abusing this for the past few years, it's great:
>> http://seb.mondet.org/software/pvem/index.html
>> http://seb.mondet.org/software/pvem_lwt_unix/index.html
>> http://seb.mondet.org/talks/compose2015/#/25
>> http://seb.mondet.org/talks/compose2015/#/26
>> On Tue, Feb 3, 2015 at 12:10 PM, Daniel BÃnzli
>> <daniel.buenzli@xxxxxxxxxxxx> wrote:
>>> Le mardi, 3 fÃvrier 2015 Ã 16:55, Christophe Troestler a Ãcrit :
>>> > Please lay down a concrete interface showing of what you mean. I
>>> > think we all agree on the goal of writing robust software, we need to
>>> > move the discussion to concrete proposals.
>>> Sorry don't have the time to work on this; these things come out of
>>> writing code. But as a start I don't see what's the problem with the basic
>>> result monad everybody knows (e.g. see here [1,2]) along with a few
>>> with_resource combinators based on some kind of `finally` [3] and stick to
>>> polymorphic variant errors â along, of course, with Format pretty printers
>>> for these something that is often annoyingly absent in APIs. And I would
>>> completely forget about using lwt's failed state (i.e. only to trap
>>> unexpected exceptions at the highest level).
>>> Best,
>>> Daniel
>>> [1]
>>> This deals only with string errors so it should be generalized to [2],
>>> but a few of the error handling
>>> combinators may be interesting.
>>> https://github.com/samoht/assemblage/blob/master/lib/assemblage.mli#L708-L744
>>> For example `reword_error` a quick combinator that allows to transform a
>>> lower-level error to a higher level one, i.e. give more context higher up
>>> when you have the info about what you are doing. Since we are using strings
>>> here it's also easy to stack the errors if you wish so (~replace:false
>>> argument) from the lowest-level of what went wrong (e.g. the actual utility
>>> invocation error) to what you were trying to do (e.g. determine the number
>>> of processors in the system) which makes error diagnosis much easier
>>> (context + no error info is lost). Not that it wouldn't be impossible with
>>> lists of polyvars, but one has to see how it comes out in practice. A few
>>> examples:
>>> https://github.com/samoht/assemblage/blob/master/lib/as_conf.ml#L420-L428
>>> https://github.com/samoht/assemblage/blob/master/lib/as_conf.ml#L543-L548
>>> [2]
>>> This is the classical generalized result type for dealing with errors.
>>> http://erratique.ch/software/fut/doc/Fut.html#TYPEresult
>>> http://erratique.ch/software/fut/doc/Fut.html#VAL(&>>=)
>>> (http://erratique.ch/software/fut/doc/Fut.html#VAL(&%3E%3E=))
>>> http://erratique.ch/software/fut/doc/Futu.html#VALread
>>> [3]
>>> http://erratique.ch/software/fut/doc/Fut.html#VALfinally
>>> This could also be modified or another version provided to propagate
>>> possible errors in the finally handler in the concurrency monad itself.

Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA

MirageOS-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.