-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Should use exit code to distinguish between no results and an invocation error #1159
Comments
With respect to invalid invocations, yes, that is indeed a bug. It's due to the fact that we let our arg parser exit the process for us if there's an incorrect argv. Instead, we should use The latter part of your bug report is more interesting, and it's less clear whether there's anything to do. Certainly, ripgrep does not match grep's behavior, but that is not in and of itself a reason to change something. In particular, ripgrep only emits a
Where grep differs on this point is that it seems to emit a
I don't really know what the "right" behavior is here. How do you want to use the exit status specifically? |
I'm using ripgrep (or ag, or ack etc) in the Ferret Vim plug-in and I'd like to provide better feedback when the user does something wrong. Right now it will say "no matches found" even if they passed a bad path or a non-existent option. |
@wincent That doesn't quite cover all our bases though... What do you want to do when a non-catastrophic error occurs but a match was found? Do users see the error messages emitted by ripgrep? |
I think making 1 what it means in grep makes sense (ie. no matches were found, but there were no errors and nothing obviously wrong that the user should "fix"). 2 to mean something went wrong, catastrophic or otherwise, irrespective of whether any (partial) results happened to get turned up on the way; if the tool really wants to, it can try to parse out the results, or the errors, or both. |
@wincent Thanks for the comment, but I don't think that really helps me make my decision. Could you explain more about the user experience instead? |
Right now:
Ideally, I think they'd instead see:
The first two cases are the common path and already work as expected. It's that last one which is rarer, but currently can't be handled well because it is ambiguous (Ferret would need to parse the error output. Empty output + exit code 1 means no results; non-empty output plus non-zero exit code means "something went wrong"; but it would be nice to tell this from the code without relying on a fragile parsing heuristic). |
OK, thanks for explaining that. I now have a more specific question.
What does Ferret do today with error messages that ripgrep writes to stderr? Does it show them to users? Also, just to make sure we're in sync, GNU grep's exit status behavior is documented as:
If ripgrep behaved like the above, would that resolve your concerns? |
Currently Ferret "swallows" error output. It's visible only if the user runs |
It feels to me like this is a fundamental problem here. Even if I change ripgrep's approach to handling exit statuses, you still have problems like, "users can't tell whether they supplied an invalid regex pattern or whether a search was executed and couldn't find any hits but also errored on reading a particular file." In both of those cases, looking at the messages of stderr clarifies what happened. But otherwise, both instances would produce exactly the same exit status with nothing printed to stdout. |
If Ripgrep exits with status 2 I will show the error output. Otherwise it goes to the Vim quickfix listing. |
Ah interesting, OK. I think I'm convinced then, and we can just implement grep's exit status semantics. |
Previously, we relied on clap to handle printing either an error message, or --help/--version output, in addition to setting the exit status code. Unfortunately, for --help/--version output, clap was panicking if the write failed, which can happen in fairly common scenarios via a broken pipe error. e.g., `rg -h | head`. We fix this by using clap's "safe" API and doing the printing ourselves. We also set the exit code to `2` when an invalid command has been given. Fixes #1125 and partially addresses #1159
What version of ripgrep are you using?
Describe your question, feature request, or bug.
I see that due to #948 ripgrep learnt how to distinguish errors (exit code 2) from no results (exit code 1), like Grep.
However, if you invoke
rg
with a non-existent flag, you'll still get exit code 1, which means that there is no way to programmatically distinguish between no results and a botched invocation.For comparison,
grep
exits with status 2 for unrecognized flags.ack
exits with status 255 for unrecognized flags.ag
suffers from the same problem, exiting with 1 indistinctly for bad invocations and for no results (issue: ggreer/the_silver_searcher#1298).FWIW, I wasn't able to get
rg
(at least not v0.10.0) to return an exit status of 2, despite what #954 ostensibly does:Note that it's still exiting with status 1.
The text was updated successfully, but these errors were encountered: