-
-
Notifications
You must be signed in to change notification settings - Fork 299
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
RFC: Should external command non-zero exit status always throw an exception? #497
Comments
I'll also point out that the fish project has discussed implementing something akin to the current elvish behavior. Details about how it should work haven't been thoroughly worked out but the consensus is it should not be the default behavior. It needs to be opt-in. Probably by annotating block commands. For example,
What I'm proposing for elvish is the equivalent of that idea. |
@krader1961 I'm not sure I agree with your proposal. While the exception behavior takes some time to get used to, I think it's good default behavior. However, as you say, non-zero status doesn't always indicate an error - many programs use it simply to indicate different types of result. What I would like is to have better exception handling - the ability to query the exit code, to compare exceptions, etc. Then it would be easy to code wrappers and extensions to the default rule. |
Yes, in theory something like my proof of concept
I actually implemented both and it works. If I run This situation is analogous to whether a network firewall should be primarily based on blacklist or whitelist rules. The current Elvish behavior is in some sense "safer" just as a firewall based on whitelist rules is safer and more secure. But it is also much harder to use and requires more configuration (e.g.,
|
That entangles exit status with
How would that interact with builtins and functions? Does As you said, Elvish adopts the "better safe than sorry" approach towards errors. It is really hard to make sure that a certain external command behaves the way you want, so I believe that behaving defensively and treating non-zero exit statuses as exceptions is the only reasonable default, even if it does not make sense in every case. The mechanism to override the default behaviour should be orthogonal to other features, and explicit. I am thinking of something that is a combination of technical solution and community convention:
|
I could probably live with the default behavior being to raise an exception for a non-zero status if there were a succinct syntax for dealing with it. Such as your proposed What about exit statuses that indicate the process terminated due to receipt of an unhandled signal? Should those always be translated to an exception? I'm inclined to say, yes. In fact, it would be useful to make that a distinct exception type. Possibly with
It was my understanding that functions don't have an exit status. Certainly the
I can't think of a good use for making Obviously there can be interesting situations outside the normal linear flow of a script or function. For example, what happens to |
My approach, which I also recommend for elvish, is implemented in NGS (alternative shell which is under development) and described in my blog post. Here are the main points: Step 1
I am sure that running Step 2 Additional syntax
|
@ilyash Thanks for the detailed explanation. Some comments: You have demonstrated using The |
In case you are not familiar with Elvish terminology, when I say "module", I mean reusable Elvish source files that are isolated by namespacing and potentially developed by different people. It is akin to modules or packages in most other modern languages. I find a bit of dilemma to decide whether
|
Note that you can add your own
I guess yes but in NGS,
In NGS |
In fact, @ilyash's |
Yes, @zzamboni , visually, functionally and use-wise they are very similar. The implementation is completely different. |
I'm going to close this because I've gotten accustomed to the elvish behavior. I think the real problem here is that the exception object doesn't make it easy to extract relevant facts such as the exit status or signal number that terminated the command. That, however, is being discussed in #208 and #765. Furthermore, I now agree with almost all of @xiaq's concerns expressed in his first comment. I think making the exception object "richer" (e.g., adding |
I've been exploring Elvish for a few weeks and really like most of what I see. Including the fact it's written in Go rather than C++, the concept of namespaces, using exceptions to signal conditions like the loop should be terminated, etcetera. I can live with the fact it is still rapidly evolving and backward incompatible changes are still occurring with some regularity. There is, however, one behavior that will keep me from using Elvish: automatically converting a non-zero exit status by an external command into an exception. The reason is that there are way too many commands that use a non-zero status to indicate a non-fatal condition. The canonical example is
grep
which terminates with status one if no lines matched the regex. Having to put every such command in atry { } except { }
block is not friendly, error prone, and ugly. My proposal is to map non-zero exit status to an exception only if the command is run in the context of atry { }
block. Thoughts?If this proposal were implemented I also think there should be a variable analogous to bash's
$?
or fish's$status
that automatically captures the exit status. I've implemented the following proof of concept function to prove that it can be done using Elvish script but it really should be default behavior:The text was updated successfully, but these errors were encountered: