navi icon indicating copy to clipboard operation
navi copied to clipboard

How can we deal with <variables> that can fail?

Open i30817 opened this issue 3 years ago • 4 comments

Is your feature request related to a problem? Please describe. I opened this as a feature request because it's not a bug.

Basically i have a long pipe that can fail early, ie: i'm taking a value from the internet, to then text process it to 'select 1' before doing something else.

Sometimes, it's possible to take the 'command that can fail' out of the navi variable, if it doesn't affect the options shown by fzf because the 'caching' is implicit, as when you fetch a origin in git, the subsequent commands have the information cached locally. This is good. Sometimes, the way to do that is more complicated if the command does directly show the result with no caching, for instance git ls-remote. I could always store it on a temporary file and use that temporary file on the <var> and extract the command out but i'm not sure where to declare the mktmpfile command and if this is even needed.

Describe the solution you'd like I was wondering if "$?" will work for <var> declarations so i could do BASH_VAR=<var>;
STATUS=$?; \

and check if the 'navi var command', even if it's a pipe (even if i have to use PIPESTATUS instead). This doesn't give me a lot of confidence because fzf is doing a lot of work inbetween this <var> and the STATUS assignment.

I don't know the best way.

Describe alternatives you've considered Extract the command that can fail (if you're lucky it's only one) outside, cache it, check it for failure and exit if so, use the cache file in the navi <var>.

I was thinking of placing this at the start of a navi file:

tmpfile=$(mktemp /tmp/github-pullrequests.XXXXXX) ;file descriptors for reading and writing respectively exec 3>"$tmpfile" exec 4<"$tmpfile" ;this removes the file once all file descriptors are gone rm "$tmpfile"

Then do the command and check the result, then just massage it into the form of the options i want to show, write the output into the file and in the navi var just read it before using. I'm unsure i have to declare open file inside a '# option (bash commands) i usually use to create navi rules or i can declare it outside as shared. Can I?

Additional context Add any other context or screenshots about the feature request here.

i30817 avatar Nov 21 '21 01:11 i30817

Turns out you can't do this (store in a file before the command) because apparently <vars> are run before your code runs. This is kind of problematic even if you can make them 'indifferent' to the code supposedly before they're used, in terms of checking for failure of a pipe (or just normal failure).

How can i do this?

edit: i guess i can depend on the pipe having a 'empty' result if i can be sure that the failure sends its output to stderr and leaves stdout clean...

Not very reliable imo.

edit2: yup. 'Empty' options list are not autoselected but they cause navi to stop. This means that error handling of this limited kind is useless because navi will just not run it and the experience is kind of bad too - you select a none 'value', but have a generic error message about the value being empty:

Caused by: 0: Failed to replace variables from snippet 1: finder was unable to prompt with suggestions 2: Unable to get output 3: Not sufficient data for single selection

Should i just embrace the happy path? Can i make navi error out early on a empty list for the possibilities and not force a selection, and change this message, if i go this way?

i30817 avatar Nov 21 '21 02:11 i30817

I'm not sure I totally understand your use case, but I believe this should be a workaround:

% err

# check for error
log="<log>"
if [ -n "$log" ]; then
   echo "my git log has <words> words"
else
   echo "failed to get git log"
fi

$ log: echo "foo bar"
$ words: echo "$log" | wc -w | xargs

In the happy path, my git log has 2 words will be printed.

In case getting <log> fails, failed to get git log will be printed.

denisidoro avatar Nov 22 '21 11:11 denisidoro

The only caveat is that if log fails, you'll need to press enter on a empty selection.

Printing an empty string does the trick, though:

$ log: echo ""; exit 1

This is probably a bug.

If there's a $ line for variable <x> and the output of <x> is empty, navi shouldn't ask the user for selection.

denisidoro avatar Nov 22 '21 11:11 denisidoro

On second thought i don't actually want to continue if something happens to return nothing. I like how it is now - fail fast when you're supposed to ask the user for info but one or more of the prerequisites fail, like the internet and you get a empty string - with the exception that i can't customize the exit stdout.

i30817 avatar Nov 24 '21 22:11 i30817