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

Re: Exception handling and "trap" vs. TRAPNAL()

On Oct 3,  9:57am, Peter Stephenson wrote:
} Subject: Re: Exception handling and "trap" vs. TRAPNAL()
} Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
} > In zsh prior to 4.1.something, an error condition in an inline trap
} > *WAS* passed through to the calling context.
} it doesn't look like the change was intentional, even though arguably it
} should be the way it now is.

It could also be argued that, if the trap should behave like an "eval",
it ought to set $? = 1 when an error occurs inside the trap (but still
not cause an interrupt condition).  The example of bash2 contradicts
that position.  Can anyone who is reading this try ksh?
} > E.g., in bash2 a global INT trap does not prevent the function from
} > being interrupted by a SIGINT; instead it handles the signal in the
} > context where the trap command was run.  Similarly an ERR trap stops
} > being tripped during the body of the function, but remains in effect
} This is presumably implementable without too much horror, since we
} can already save and restore traps.

It's worse than just saving and restoring traps.  It requires treating a
function call like a subshell, in that both the function and the caller
get the SIGINT, the function is interrupted, and the caller's trap is

} It would probably now need to be an option, though.


} > The zsh "always" syntax could -- and perhaps even should -- have been
} > implemented equally well as a new syntax for the "eval" builtin, much
} > like Perl's "eval" can be followed by a curly-bracketed block instead
} > of a string.
} That's not particularly natural in zsh.

I didn't really mean that the syntax would be exactly like Perl's, just
that the behavior would be.  If you wanted to implement something as
close as possible to "always" in an older version of zsh, you'd do
something like:

    eval "print this is the try block"
    print "this is the always block"
    if (( TRY_ERR == 0 ))
      print "this is what comes after the always block"
      # This is a stupid way to reset $? without exiting from the
      # parent shell script when we aren't in a function body.
      ( return TRY_ERR )

} > Given all of this plus the bash2 behavior, I'm inclined to add a few
} > more words to the documentation and apply *neither* of the patches
} > from workers/21804.  Further, *IF* we were going to choose one of
} > those patches to apply, I'd say it should be the first one, to make
} > TRAPNAL ignore errors too.
} It looks like the reason for the error to be propagated is receding into
} history and I'd be perfectly happy with that patch.

As I said, I'm actually leaning towards no patch at all.  However, the
reason for propagating the error isn't actually receding, because Raúl
says he needs that behavior, and given "always" it really is useful.

Here's a possible compromise:  Use my second patch, but propagate the
error if and only if we're in the try-block of an always-construct.
That's guaranteed not to break old code, and continues to behave like
bash2 in the absence of "always".  Can dotrapargs() determine that it
is in "always" context without too much trouble?

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