Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Question about err_return



Radon Rosborough wrote on Sun, 20 Aug 2017 22:28 -0700:
> why does the following:
> 
>     function { setopt err_return; false; echo 'oh no' }
> 
> print nothing, while
> 
>     function { setopt err_return; false; echo 'oh no' } && true
> 
> prints 'oh no'? This seems very inconsistent to me, as I would expect
> the result of 'x && true' to be the same as 'x' in all circumstances.
> 
> Now I found an old thread [1] about this, and the resolution was that
> this behavior was unsurprising since err_return emulates err_exit. The
> idea is that err_exit is automatically disabled for all child code
> whenever a function is invoked as part of a conditional expression,
> and so err_return does the same.

I'm having trouble seeing how this is not simply a bug.  Consider:
.
    % f() { setopt err_return; false; echo 'this runs' }
    % f && :
    this runs

The command "false" had a non-zero exit status, and the enclosing function
continued to execute.  That's exactly what the documentation promises would
not happen:
.
       ERR_RETURN
              If a command has a non-zero exit status, return immediately from
              the enclosing function.

I don't see how the fact that f's callsite is the left-hand side of a '&&'
is relevant here.  It would be relevant to deciding whether f's non-zero
return value should cause the _caller_ to return/exit immediately as well,
but that has to do with the ERR_EXIT / ERR_RETURN settings in the caller
scope, and shouldn't change f's behaviour.  (The invariant you proposed —
«foo» ≡ «foo && true» — is a good one.)

The analogy with ERR_EXIT's treatment of '&&'/'||' should kick in when those
oprators are used _inside_ the function:
.
    % f() { setopt err_return; false || true; echo 'this should be printed' }

The callee function behaves the same way if err_return is set in the caller, as
Bart suggested in the original thread.

> But we have an err_return in Zsh. Is it worth breaking backward
> compatibility to improve the usability of err_return?

Well, I'm certainly not suggesting to change this before 5.4.2 (which is
expected soon).  But we could change this after 5.4.2 and let it soak in master
until 5.5.  Thoughts?

> If not, I would like to know how I can otherwise implement error
> checking in my scripts. I need for any unexpected error to cause an
> immediate return from the enclosing function, which is how err_return
> is advertised in the Zsh manual [3], but not how it actually works at
> present.

Yes, the documentation doesn't match the implementation, so we need to fix one
or the other.

Thanks for the report, and for digging up those old threads.

Cheers,

Daniel



Messages sorted by: Reverse Date, Date, Thread, Author