Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design and implement I/O error handling strategy #6163

Closed
brson opened this issue May 2, 2013 · 6 comments · Fixed by #11946
Closed

Design and implement I/O error handling strategy #6163

brson opened this issue May 2, 2013 · 6 comments · Fixed by #11946
Assignees
Labels
A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@brson
Copy link
Contributor

brson commented May 2, 2013

Getting error handling right is difficult. Lot of ins, lot of outs, etc.

Discussion here: https://mail.mozilla.org/pipermail/rust-dev/2013-April/003746.html

@ghost ghost assigned brson May 2, 2013
@glaebhoerl
Copy link
Contributor

FWIW a brief recap (and slight evolution) of my proposal:

-2. Make it possible for a supervising task to intercept the argument its child task gives to fail!()
-1. Make try() return that in the Err variant of Result
0. Make try() have very low overhead

  1. I/O operations indicate errors by raising conditions, and if the error can't be repaired, fail!()ing with a description of the error
  2. The conditions are (logically) such that they allow for the handler to recover from the error
  3. The exception to 1+2 is close(), which consumes the argument File and returns a (potential-)error description directly

Benefits:

  • Straight-line I/O code without error handling is straightforward and concise.
  • If the programmer wants to recover from an error and keep going, she can use a condition handler.
  • If the programmer wants to respond to an error in some other way, she can use try().
  • Files, if they are in scope, are statically guaranteed to be open and in a good state. The programmer does not have to handle or care about the possibility that they might not be, similarly to non-nullable pointers.
  • If the programmer wants to have a File managed by the garbage collector that can nonetheless be closed early, she can use @mut Option<File>.

Other possibilities:

  • Provide impl<S: Stream> Stream for Option<S> and/or for Result<S, IoError> (likewise Reader/Writer), which wraps calls to try() and indicates errors by writing None/Err into self. Not sure what to do in the case where the return value was supposed to be read from the stream, probably return a default.
  • Make the types also reflect readability/writability. So instead of just File, there would be File, ROFile and WOFile, of which the latter two would implement Reader but not Writer and vice versa. Correspondingly open() would bifurcate into open(), open_ro(), and open_wo(), and the FileAccess enum would disappear.

@brson
Copy link
Contributor Author

brson commented May 4, 2013

@glehel thanks for the comments.

Making fail! propagate it's argument is an idea I support. If it's to be used to handle arbitrary error types then it requires some sort of dynamic typing that we don't have yet.

Relying on try for error handling in this case is viewed by some as too risky - it may never be fast enough. They would like to be able to recover without crossing the task boundary.

Being able to recover from a close error is a good argument for the close method.

@thestinger
Copy link
Contributor

On Sat, May 4, 2013 at 7:56 PM, Brian Anderson [email protected]:

@glehel https://github.com/glehel thanks for the comments.

Making fail! propagate it's argument is an idea I support. If it's to be
used to handle arbitrary error types then it requires some sort of dynamic
typing that we don't have yet.

Relying on try for error handling in this case is viewed by some as too
risky - it may never be fast enough. They would like to be able to recover
without crossing the task boundary.

Being able to recover from a close error is a good argument for the closemethod.

AFAIK, you can check for any errors that would happen on close with a
flush method on all the platforms Rust runs on.

@glaebhoerl
Copy link
Contributor

@brson right, making try() fast enough is a precondition for the whole thing (hence "0."). If it can't be done then that's that, need a different plan.

...although. If the Reader/Writer/Stream impls for Result (as I conjectured under "Other possibilities") could be implemented not by wrapping try(), but instead directly/natively, then perhaps the whole thing could still be salvaged with most of the benefits intact? In that case the performant way to handle errors (without crossing the task boundary) would just be to use Result<File, IoError> rather than File. (And then if try() does become fast enough at some later point, so much the better.)

@brson
Copy link
Contributor Author

brson commented Jun 20, 2013

Won't be done for 0.7

@huonw
Copy link
Member

huonw commented Sep 10, 2013

Triage: nothing particularly to say, although the new std::rt::io uses conditions more than the old one; I believe the exact arrangement is still fluid so I can only assume this bug is still relevant.

@bors bors closed this as completed in cb40eba Feb 3, 2014
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 24, 2020
…1995

Remove lazy_static completely and use once_cell feature instead

Follow-up to rust-lang/rust-clippy#6120

This removes the last remaining `lazy_static` usages and replaces them with `SyncLazy` from the `once_cell` feature.

---

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants