Here is a patch that updates the documentation of the ERR_EXIT and ERR_RETURN options. The main improvement is to better explain when these options are ignored. As it may be a bit difficult to read it directly in the patch, I reproduced below the updated documentation: *ERR_EXIT* > If a command has a non-zero exit status, execute the tt(ZERR) > trap, if set, and exit. > The option is ignored when executing the commands following tt(while), tt(until), tt(if), or tt(elif), a pipeline beginning with tt(!), or > any command other than the last in command list containing tt(&&) or > tt(||). Hence neither `tt(if foo; then true; fi)', nor `tt(foo && > true)' trigger exit when tt(foo) returns with a non-zero exit status. > Note that if tt(foo) is a function, the option is also ignored during > its whole execution. > The option is also ignored when executing a complex command (tt(if), > tt(for), tt(while), tt(until), tt(repeat), tt(case), tt(select), > tt(always), or a list in braces) if its exit status comes from a > command executed while the option is ignored. Hence, the tt(if) > command in `tt(if true; then false && true; fi)' does not trigger > exit. > Finally, the option is also ignored while running initialization > scripts and inside tt(DEBUG) traps. In the latter case, the option is > handled specially: it is unset on entry to the trap. If the option > tt(DEBUG_BEFORE_CMD) is set, as it is by default, and the option > tt(ERR_EXIT) is found to have been set on exit, then the command for > which the tt(DEBUG) trap is being executed is skipped. The option is > restored after the trap exits. Exiting due to tt(ERR_EXIT) has certain interactions with asynchronous > jobs noted in > ifzman(the section JOBS in zmanref(zshmisc))\ > ifnzman(noderef(Jobs & Signals)). > Note this behaviour is not disabled in interactive shells --- > a non-zero status on the command line causes the shell to exit. *ERR_RETURN* If a command has a non-zero exit status, return immediately from the > enclosing function. Except for the exceptions described below, the > logic is the same as that for tt(ERR_EXIT), except that an implicit > tt(return) statement is executed instead of an tt(exit). This will > trigger an exit at the outermost level of a non-interactive script. > At the top level of an interactive shell, it will trigger a return to > the command prompt; in other words, the sequence of commands typed by > the user may be thought of as a function for this purpose. > Unlike for tt(ERR_EXIT), when a function is called while the option is > being ignored, the option is NOT ignored during the execution of the > function. Hence, if tt(foo) in `tt(foo && true)' is a function, code > inside it is considered separately: it may force a return from tt(foo) > (assuming the option remains set within tt(foo)). > Like for tt(ERR_EXIT), the option is ignored inside tt(DEBUG) traps > but it's not unset on entry to the trap and setting or unsetting it > inside the trap has no special effect. > If tt(ERR_RETURN) and tt(ERR_EXIT) are both set, the latter takes > precedence. Hence, exit rather than return is triggered when a command > has a non-zero exit status. Philippe