[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [MirageOS-devel] Error handling in Mirage - request for comments!
On 22 March 2015 at 15:02, Daniel BÃnzli <daniel.buenzli@xxxxxxxxxxxx> wrote: > Le dimanche, 22 mars 2015 Ã 14:43, Thomas Leonard a Ãcrit : >> Yes, but the question is whether this information is worth the >> overhead. > > Again programmatically there's no overhead if you are using the right set of > combinators and type definitions. You can say there is a performance overhead > but at a certain point you have to choose whether you want correct, safe and > reliable systems or favour performance. I'm strongly in favour of the former > and have both whenever possible. > >> - We must assume that some implementation of a Mirage module type may >> produce an error (they're all about I/O, after all), so annotating >> every function to say this doesn't provide any extra information. > > This misses the point. Having every functions annotated provides you > information *in the type system* which gives you a mechanism to *enforce* > good and correct error handling in the program. > > Using exceptions doesn't allow you to enforce error handling and is otherwise > very dangerous because 1) You basically don't know when they happen except > through documentation, so they are easy to miss and not handle them (if > documentation exists at all...) 2) They disrupt your whole callstack, > possibly leaking resources and putting your program in a bad state by > breaking invariants that should hold in our system 3) The source of the > exception may be hard to track 4) They are hard to reason about and handle > correctly. The only case of handling the current polymorphic errors in Mirage so far presented is this case from ocaml-tls (thanks David!): https://github.com/mirleft/ocaml-tls/blob/master/mirage/tls_mirage.ml#L51 let lift_result = function | `Error e -> `Error (`Flow e) | `Eof | `Ok _ as r -> r let check_write flow f_res = let res = lift_result f_res in ( match (flow.state, res) with | (`Active _, (`Eof | `Error _ as e)) -> flow.state <- e ; FLOW.close flow.flow | _ -> return_unit ) >> return res As you say, it's easy to reason about this code if we assume that exceptions don't exist: - If the underlying FLOW returns any error on write, then the TLS state transitions to `Error and cannot be used again and the FLOW is closed. However, exceptions do exist in OCaml. The actual behaviour therefore is something like: - On `Refused, `Timeout or `Unknown, the flow is closed and the TLS system transitions to `Error. - On Division_by_zero, Not_found, Assert_failure or Stack_overflow, the flow remains open and the TLS state can continue to be used. It seems unlikely to me that this is the desired behaviour. If all errors were exceptions then the code would likely handle all these cases. (however, it's not clear to me exactly what this code is trying to achieve, so I could be wrong) -- 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 MirageOS-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/mirageos-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |