There have been some recent grumblings [1] about the use of conditions in the new runtime's I/O system. It was decided awhile back [2] that we'd try out the use of conditions for error handling in the new runtime. This has manifested itself in the `io_error` and `read_error` conditions inside of the `rt::io` module.
I've done some recent work [3][4] in removing std::io, and I've personally found the use of conditions a little painful. Here's a few of the problems that I ran into: * Do you catch io_error or read_error? Catching both is really painful, and remembering which one to catch is sometimes more painful. This could be alleviated by having a read_error raise on an io_error if there is no handler registered, so this is certainly not a show stopper. * If you want to catch an error, it's pretty ergonomically painful let mut err = None; let ret = do io::io_error::cond.trap(|e| err = Some(e)).inside { // some i/o operation }; match err { None => {} // yay we succeeded Some(e) {} // oh no, an error! } This seems like a lot of verbage for doing something as simple as checking to see whether an i/o operation resulted in an error or not. * Using closures prevents certain kinds of movements between values. This is a known limitation of closures today and may be alleviated by the closure redesign, however. This isn't quite a show stopper, but it is another pain point. * The "blanket error condition" isn't really being used for what I thought conditions were intended for, which is somehow continuing the work at the raise site using the result of the condition. Because the io error conditions both return (), then there's not really anything you can do but hope to squirrel away the conditions somewhere. These various reasons have added to the pain points when dealing with error handling in the new runtime. I certainly don't think that we should remove conditions entirely (they're an effective error handling system for many purposes), but for the use case of simply reporting errors I don't feel that they're quite appropriate. All that being said, we're not making much progress without an idea of where to possibly go next. Right now, the current idea is to create an Error trait and have I/O operations return Result<T, ~Error> instead of Option<T>. This would mean that Reader/Writer and other associated traits would be defined for Result<T, ~Error> where T: Trait (so you could still chain operations easily), and you could very easily check for an I/O error. This is all still pretty early-stage, though, and we certainly haven't committed to anything just yet. I wanted to canvas everyone to see what others' opinions are about using conditions for error handling. I'm certainly not the only use-case so far! [1] https://github.com/mozilla/rust/issues/9795 [2] https://mail.mozilla.org/pipermail/rust-dev/2013-April/003746.html [3] https://github.com/mozilla/rust/pull/9749 [4] https://github.com/mozilla/rust/pull/9888 _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev