Skip to content

Tracking issue for RFC 1937: ? in main #43301

Closed

Description

@aturon

This is a tracking issue for the RFC "? in main" (rust-lang/rfcs#1937).

Steps:

Stabilizations:

Related issues:

Unresolved questions:

Activity

  1. added
    B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.
    T-langRelevant to the language team
    on Jul 17, 2017
  2. ketsuban commented on Jul 18, 2017

    @ketsuban
    Contributor

    This comment by @Screwtapello seems to have been made too close to the end of FCP for any alterations to be made to the RFC in response to it.

    In short: the RFC proposes returning 2 on failure on grounds which, while well-founded, are obscure and produce a slightly unusual result; the least surprising thing is to return 1 when the program has no indication it wants any more detail than just success or failure. Is this sufficiently bikesheddy that it can be discussed without it feeling like we're perverting the RFC process, or are we now locked into this specific implementation detail?

  3. Screwtapello commented on Jul 18, 2017

    @Screwtapello
    Contributor

    This is specifically about the case when a sub-process (implemented in Rust) has no information to give, beyond a binary "everything's fine"/"something went wrong".

  4. NoraCodes commented on Jul 18, 2017

    @NoraCodes
    Contributor

    Some scripts use exit codes as a way to get information from a sub-process.

    That behavior is always extremely dependent on the program being called except in that non-zero means failure. Given that std::process::exit with a main-function wrapper and a lookup table is going to remain the best option for those who want a more articulate exit status no matter what is done, this seems like a mostly insignificant detail.

  5. glaebhoerl commented on Jul 18, 2017

    @glaebhoerl
    Contributor

    I think the exit code should be added to the unresolved questions list. @zackw also opened a related internals thread.

  6. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    on Jul 27, 2017
  7. liigo commented on Aug 11, 2017

    @liigo
    Contributor

    Many people agree that the exit code should be 1 on failure (instead of 2):
    https://www.reddit.com/r/rust/comments/6nxg6t/the_rfc_using_in_main_just_got_merged/

  8. added this to the milestone on Sep 15, 2017
  9. 225 remaining items

  10. Stargateur commented on Apr 7, 2022

    @Stargateur
    Contributor

    @joshtriplett Why would you oppose to let such scenario be handle by exit() feature ?

  11. joshtriplett commented on Apr 7, 2022

    @joshtriplett
    Member

    Why would you oppose to let such scenario be handle by exit() feature ?

    Because exit codes are a well-established mechanism that I'd like to see integrated with ?-based error handling, and I don't see any reason not to offer first-class support for them. And because exit doesn't necessarily allow a program's cleanup to run, whereas returning from main does.

  12. Kixunil commented on Apr 7, 2022

    @Kixunil
    Contributor

    My favorite example when multiple error codes are useful:

    grep -q "$needle" "$haystack_file"
    case $? in
        0)
            handle_found
            ;;
        1)
            handle_not_found
            ;;
        *)
            # grep itself failed
            exit 1
            ;;
    esac

    The behavior of grep is documented so the code above is sensible. Pulling this out of stderr would be very annoying and possibly unreliable. A Rust program should be able to support something similar.

  13. lnicola commented on Apr 7, 2022

    @lnicola
    Member

    Pulling this out of stderr would be very annoying and possibly unreliable.

    And error messages are often localized.

  14. BurntSushi commented on Apr 7, 2022

    @BurntSushi
    Member

    I think we could have @BurntSushi input on error code since he is the creator of ripgrep that have a custom error code like grep (legacy reason I guess)

    Here's the relevant code:

    https://github.com/BurntSushi/ripgrep/blob/ced5b92aa93eb47e892bd2fd26ab454008721730/crates/core/main.rs#L67-L73

    I don't think it's for legacy. @Kixunil gave a good example of why you really want to distinguish between "success," "no match" and "error." If ?-in-main doesn't support returning exit codes beyond "success" or "failure," then yeah, I would just keep using process::exit.

    I read the comments above and I don't see any compelling reason for limiting ourselves to "success" or "failure." The docs can clearly state that 0 tends to mean success, but there is otherwise no agreed upon standard for what other numbers mean. So yeah, I think we should at minimum provide a way for constructing an ExitCode from a u8.

  15. Lucretiel commented on Apr 7, 2022

    @Lucretiel
    Contributor

    I'll also shout out git bisect, which is the best example I know of a program that consumes error codes from another program. Git bisect wants to find the first commit that fails to pass a test (presumably where a bug was introduced), so you give it a command and it performs a binary search, running the command in a loop on various commits. It interprets 0 as "build success", 125 as "skip / not testable", 1-127 as "build failure", and 128+ as "stop bisecting". It's a really excellent system for tracking down when a particular bug was introduced in a long commit history.

  16. mathstuf commented on Apr 7, 2022

    @mathstuf
    Contributor

    It's also relevant to skipping tests in various test suites (autoconf and automake use 77 to indicate that a test should skip. See this pre-RFC IRLO thread for more prior art there.

  17. Stargateur commented on Apr 7, 2022

    @Stargateur
    Contributor

    Because exit codes are a well-established mechanism that I'd like to see integrated with ?-based error handling, and I don't see any reason not to offer first-class support for them.

    That false, exit code are not at all well established mechanism, they are on the contrary implemented behaviour so it's hard to rely on them outside of linux and even on linux it's a meh and some system doesn't support them at all. I listed some reason to not offer first class support for them. I think we must clearly document it as implementation behaviour.

    And because exit doesn't necessarily allow a program's cleanup to run, whereas returning from main does.

    My point was to use exit at the end of the main, I think it's should be the same cleanup degree, but agree this is a big con to exit().

    I don't think it's for legacy. @Kixunil gave a good example of why you really want to distinguish between "success," "no match" and "error." If ?-in-main doesn't support returning exit codes beyond "success" or "failure," then yeah, I would just keep using process::exit.

    I believe grep example is a very bad one of using error code, other are fine but on grep make the program return an error for not found is rather counter intuitive and probably have been source of bug over time. A bash script generally want to stop at any error using:

    set -e
    set -o pipefail

    Using grep in a bash script with this would make the script stop for empty result, quite weird IMO. Any code/script that want to stop at the first error would be annoying by the grep behaviour. I think an grep option that return the number of match would be better. I don't know if this option exist but something like this count=$(grep --count "$needle" "$haystack_file") and if [ "$count" -eq "0" ];. (combine with an option that stop at first result if you only want to know if there is at least one match)

    And error messages are often localized.

    Obviously use stderr in a script require the program to have an option to output machine like error message, json or whatever. Something easy to parse and documented. Quite similar to Cargo metadata output.

    I didn't say they was no use-case, my point was about let the job be handle by exit() and that I think they are better way to report result than using error code. I'm also afraid this would be used badly. But I don't strongly oppose, I just raise concern. And I'm quite alone in this team so be it.

  18. yaahc commented on Apr 7, 2022

    @yaahc
    Member

    I believe grep example is a very bad one of using error code, other are fine but on grep make the program return an error for not found is rather counter intuitive and probably have been source of bug over time. A bash script generally want to stop at any error using:

    set -e
    set -o pipefail

    I'm gonna go out on a limb and say that this is a shortcoming of error handling in bash, not grep. The fact that bash makes properly handling error cases so incredibly difficult was a big factor in me getting further involved in Rust and Rust error handling in particular. I think you're absolutely right in that the state of exit codes is not okay, but this system exists, people rely on it, and we already support it. i32 is the defacto interface by which processes report errors to each other on most platforms and while I would love to see that replaced by something better in the future, I do not think parsing stderr is the fix.

  19. Kixunil commented on Apr 8, 2022

    @Kixunil
    Contributor

    even on linux it's a meh and some system doesn't support them at all

    Can you give some examples? I've been using various Linux distributions for ~14 years and never came across one that didn't support exit codes. It's true that very few programs do stupid shit around exit codes (especially not using them) but programs generally do stupid shit so that's no surprise. By limiting the API we would encourage more stupid shit, not less.

    Agree with @yaahc that set -e is <redacted slur> error handling. (I have some unpleasant experiences with it and generally avoid it.)

  20. yaahc commented on Apr 8, 2022

    @yaahc
    Member

    @Kixunil please refrain from using ableist slurs.

  21. Stargateur commented on Apr 8, 2022

    @Stargateur
    Contributor

    Can you give some examples? I've been using various Linux distributions for ~14 years and never came across one that didn't support exit codes. It's true that very few programs do stupid shit around exit codes (especially not using them) but programs generally do stupid shit so that's no surprise. By limiting the API we would encourage more stupid shit, not less.

    Sorry I wasn't clear, linux only take 8 bits of int of exit(), that why the current plan is to impl From<u8> for ExitCode. This is because linux use the rest of the int as bitfield for other info. Windows doesn't do that so you don't have same value of linux for anything > 255 and negative value are unclear too. Here we have a big difference between two major OS, then yaahc said "i32 is the defacto interface by which processes report errors to each other on most platforms" that IMO false it's a int so this isn't clear about being a i32 or other int size. Specially on embedded system where int could be 16 bits. For system that doesn't support it I don't have a list but yaahc said Wasm seem to not allow it.

    In my opinion the current limit with u8 is a nice idea, wasm limit is not a big deal and almost all systems would handle at least u8 value.

    Agree with @yaahc that set -e is error handling.

    I'm not sure I understand the same thing, English is not my best and I have no idea what "I'm gonna go out on a limb " mean. But I believe the point of yaahc was more about bash being bad at error handle in general, even just write a correct if in bash is complicated.

  22. yaahc commented on Apr 8, 2022

    @yaahc
    Member

    I'm not sure I understand that same thing, English is not my best and I have no idea what "I'm gonna go out on a limb " mean. But I believe the point of yaahc was more about bash being bad at error handle in general, even just write a correct if in bash is complicated.

    oh, sorry about that. "going out on a limb" is a saying that refers to "climbing out onto tree branch (limb)" with the idea that the branch would not do a good job supporting you and may break out from under you at any moment. In this situation, the branch represents the position I'm taking or argument I'm making, and I used that phrase to indicate that I felt I was risking push back by being critical of another language and that this is the kind of argument I normally would not make, at least not in issues like this.

  23. joshtriplett commented on May 15, 2023

    @joshtriplett
    Member

    Every usage of this tracking issue in rust-lang/rust has been stabilized. There may be further work we want to do on ? in main in the future, but the work tracked by this tracking issue seems to be done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCE-help-wantedCall for participation: Help is requested to fix this issue.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.S-tracking-design-concernsStatus: There are blocking design concerns.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE]

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions