-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking Issue for std::process error handling #73131
Comments
@rustbot modify labels +T-libs |
@ijackson Are you happy if we collapse those child issues into this one and consider everything we want to do to improve our |
I was thinking our path could look something like:
What do you think? |
In #81452, am I reading that right and you're saying it's possible to spawn a child that outlives its parent process entirely? |
As for what to make the API for
We could consider returning a I think it would be nice to try come up with a name that's a little clearer than either Command::new(adb_path)
.arg("push")
.arg(&exe_file)
.arg(&self.config.adb_test_dir)
.status()
.unwrap_or_else(|_| panic!("failed to exec `{:?}`", adb_path));
.ok()
.unwrap_or_else(|s| panic!("`{:?}` failed: {}", adb_path, s)); I don't find it clear that |
Hi. Thanks for the attention.
I was thinking our path could look something like:
1. Design our API for converting ExitStatus into a Result.
2. Update our docs (in particular our docs around ExitStatus are pretty
sparse).
3. Get the ExitStatus into Result API stabilized and update our examples to
use it instead of ignoring them.
4. Consider #[must_use] on ExitStatus.
What do you think?
The current situation seems quite bad to me but it has been like this
for quie a while. So I want to fix it in whatever way will get
general approval :-). I am fine with doing things in this order.
In #81452, am I reading that right and you're saying it's possible to spawn a
child that outlives its parent process entirely?
Yes. That is the default behaviour of fork() if you exit without
waiting for the child. This is rarely desirable.
As for what to make the API for ExitStatus into Result look like, I
arrived at success_or_else after thinking:
If it were called `or_else` it ought to take a closure. I think we
need to provide something returning a `Result` (on which you could say
`unwrap_or_else` if you wanted). Any `..._or` ought to take a
parameter for use when it's failure, as it does for `Result`,
`Option`, et al. E.g. Option has `ok_or` and `ok_or_else` taking an
E (somehow) and returning Result<T,E>.
� We should try give our methods that convert a non
Option/Result/Poll-like type into one a more semantic name, so
that you can identify it in a chain of combinators.
That suggests `.exit_ok()` to me. We don't want it to be a very long
name because this is supposed to be the easy way to do it right.
It didn't occur to me to mention something about the type in the
method name but that seems to address nicely the concern that the
combinator list is confusing otherwise.
� We don't necessarily need to introduce a new
ExitStatusError type that will look roughly the same as
ExitStatus, except implement the Error trait, because ExitStatus
is Copy, if you want to add it as context you can freely refer
to it anywhere.
I don't follow this. You're saying that the `Error` value from
`.exit_ok()` (or whatever we call it) ought not to contain the exit
status ? Or that it ought to be something much more complicated ?
I definitely don't think the usual usage pattern ought to involve
putting the exit status into a variable and then handling it again in
a closure passed to a Result combinator.
We could consider returning a io::Result<()> though, and passing a private
inner error type instead that includes the exit code in its Display message.
I find this quite unattractive. `io::Error` is primarily a container
for an OS error number for use with `ErrorKind` etc. It's capable of
containing other things mostly so that APIs (eg important traits) that
invole `io::Error` can be provided by other things. To use
`io::Error` for anything else is clumsy (and involves boxing
twice...).
(Following the discussion in my pre-RFC) I think by far the most
sensible alternative is a dedicated `ExitStatusError` which is just
the (nonzero) wait status. Then it would be Copy, Into<ExitStatus>,
and so on.
Thanks,
Ian.
…--
Ian Jackson <[email protected]> These opinions are my own.
Pronouns: they/he. If I emailed you from @fyvzl.net or @evade.org.uk,
that is a private address which bypasses my fierce spamfilter.
|
I guess in summary, I think next step in this area should probably be to work up an MR for |
Ah, what I meant here was that I don't think we should introduce a dedicated fn make_exit_status_a_result<E: Error>(self, err: E) -> Result<(), E> or: fn make_exit_status_a_result(self) -> io::Result<()> Every other |
Yeh I can't think of a case where that's ever what I've wanted! We've previously rejected attempts to add Sorry for the mix-around, would you be happy to resubmit a PR that adds |
Most of the examples in the stdlib leak the |
FYI the behaviour if you leak the child:
|
Thanks for your comments. I still think, especially after the discussion on internals, that the dedicated How about I write up my proposal in a mini-RFC style ("motivation", "alternatives" etc.) in #/73125 ? |
@ijackson No problem! I'll also go and read through the pre-RFC discussion so I'm properly informed too. |
Just added a link to rust-lang/rfcs#3362 |
Hi. This is a tracking issue for various error handling awkwardnesses in
std::process
. It seemed useful to gather them together here. I hope you consider this helpful. I don't think this needs an RFC but I can make an RFC if people feel that would be best.About tracking issues
Tracking issues are used to record the overall progress of implementation.
They are also uses as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Relevant RFCs and proposals:
Command
and a newSubprocessError
typePlatform-independent issues
#[must_use]
onstd::process::Child
(first cut in Add #[must_use] to process::Command, process::Child and process::ExitStatus #81452)#[must_use]
onstd::process::ExitStatus
(first cut in Add #[must_use] to process::Command, process::Child and process::ExitStatus #81452)output()
Result
fromExitStatus
Unix issues relating to
ExitStatusExt
std::os::unix::process::ExitStatusExt
into_raw
std::os::unix::process::ExitStatusExt
.coredumped()
methodThe text was updated successfully, but these errors were encountered: