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

Re: Inconsistent behavior of ERR_EXIT with conditionals



One last thought ... have you tried checking the behavior with both
ERR_EXIT and ERR_RETURN ?  Functions behave differently for ERR_RETURN
than ERR_EXIT.

Ha, I had the exact same thought yesterday while studying exec.c and loop.c but no, ERR_RETURN doesn't help. ERR_EXIT gets disabled on the left of "&&" and "||" and in the condition of if and loop statements. ERR_RETURN gets re-enabled on function calls. For my behavior, I too would need re-enabling but of ERR_EXIT and more importantly it would have to happen on the left of ";" (i.e., for every command that is followed by another one) rather than on function calls.

I'm still studying the code to figure out whether my behavior is at all possible and what it would require. At the moment, many parts of the code still look like black-magic but I slowly start to understand what's going on. In that regard, the description of word codes in parse.c was very helpful. I think that I now have a relatively good understanding of how the parsed code is represented overall but I'm still missing many of the details. Something that would be of tremendous help is the ability to see the parsed word codes. Is it possible to print these somehow? And/or is it possible to print the word codes as they get evaluated? I haven't seen anything to that effect. Is there anything else you would recommend that I read and/or use to better understand the codebase?

One example of a legitimate use of ERR_EXIT is to implement (shelling
out from) "make -k" where each command is distinct and you want the
build process to stop if one step is incomplete.

Although I must admit that I only very partially understand your example, I assume that you see ERR_EXIT more like a feature for other tools like "make" that need to run arbitrary shell commands than something for standalone shell scripts. I could also imagine that ERR_EXIT was originally designed for such cases. However, in my experience, ERR_EXIT is often used as a safeguard for standalone scripts. Even though it's far from perfect, it's definitely better than nothing. And, in my opinion, it's a legitimate use of ERR_EXIT, even if that wasn't its original purpose.

I'm mainly a Java developer. In Java many functions may throw runtime exceptions. You can catch and handle these but in 99% of the cases you just ignore them because you know (or assume) that they won't be thrown. Doing otherwise would be very impractical because your code would be littered with try/catch statements. Every now and then one of these exceptions that you thought could/should never be thrown is nevertheless thrown for some reason. In that case the exception goes up the call stack and, if no catch is encountered, it kills the program and prints a stack trace to the code that threw the exception. This way it's obvious that something failed. It's also easy to figure out where it happened. And, it ensures that no extra harm is done (by keeping running the program).

In the world of shell scripts, there are no runtime exceptions but some exit statuses play a similar role. Many UNIX commands and shell functions can potentially return a non-zero exit status but when you use them you often know (or assume) that they won't return a non-zero exit status. If they nevertheless do, the default behavior of shell script is to simply ignore the error. So if "cmd1" fails in "cmd1; cmd2", "cmd2" still gets executed. It's already bad that "cmd1" failed. Running "cmd2" could cause extra harm. It looks much safer to exit right after "cmd1". That's the main reason I run all my scripts with ERR_EXIT enabled.

In addition to that, ERR_EXIT also makes it easier to notice errors and to figure out where they happened, especially if ERR_EXIT is coupled with code that prints a stack trace. Without ERR_EXIT you may not even notice that something went wrong if no error message was printed (or it got swallowed).

My impression is that ERR_EXIT is commonly used for these reasons. In fact, whenever I have seen it used, it seemed to be for these reasons. But maybe I should confirm that. I'll ask some of my friends if they use it and with what expectations.

In my opinion, the only downside of that usage of ERR_EXIT is that it's far from foolproof. There are plenty of cases where just enabling ERR_EXIT won't be enough to ensure that the script halts at the first unexpected error. I would like to improve that. My zabort script already goes a long way. It works around the non-propagation issues, which are by far the main reason why just ERR_EXIT isn't enough. That's good but it would be even better if the non-triggering issues could also be solved, even if these are less common.

Philippe
 

On Thu, Nov 10, 2022 at 6:09 AM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
On Wed, Nov 9, 2022 at 5:00 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
>
> I'm going to stop responding anyway, because I'm not interested in the
> stated goal.  If others want to pursue this discussion, please go
> ahead.

One last thought ... have you tried checking the behavior with both
ERR_EXIT and ERR_RETURN ?  Functions behave differently for ERR_RETURN
than ERR_EXIT.


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