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

Reply via email to