Some time ago I started to doubt if using 'set -e' is a good idea.
I mean, if it would work as you expect it to, it certainly is a good idea to exit a script as soon as something fails. But sadly not all implementations behave similarly [1] and if you call a function from within a condition, 'set -e' gets deactivated/doesn't work.
For illustration, take a look at the following example:
Probably not what you would have expected. Not using 'set -e' is no good solution either, so, for the time being, I still use it, but I am still looking for a better solution.
If I have something I know can fail, and I want it to be able to, then calling set +e before it, and recalling set -e afterwards is the way I handle it.
But, in this case, because you're running it in a subcommand, you need to add pipefail.
set -euo pipefail
This way of making sure nothing misbehaves also locks out unset vars, which can be surprising, but also helpful.
As far as I can tell, adding pipefail or nounset doesn't change the behavior in this case.
In my opinion, the problem is that calling a function from a test expression, evaluates it in a different manner than calling it from elsewhere. That is so absurd that I wonder how it wasn't changed over the years.
I'm still looking for feedback and there's probably one more thing I want to change.
Although the fundamental problem is that errors (success/fail) and boolean values (true/false) are conflated in the status code, so it's a tough problem.
In Oil you will be encouraged to use expressions for booleans, not statements, e.g.
Obsessively checking for failures like people do in go is the "correct" way. Using && to chain groups of your commands that depend on each other also helps.
Well, I am not sure what the correct way of handling errors is. I like the concept of Exceptions, but not the results when people use them. Somehow they encourage devs to care less about error checking.
And while I appreciate the thoroughness of handling errors the Go way, I find it tiring and verbose. In many cases, you just want to exit with a specific exit code and adding 4 lines just to specify that exit code doesn't feel right.
The problem I have with errexit is that you can't rely on it. You can write your function with it (even enabling it explicitly), but later someone comes along, calls it in the wrong context and boom, your function runs without errexit.
I mean, if it would work as you expect it to, it certainly is a good idea to exit a script as soon as something fails. But sadly not all implementations behave similarly [1] and if you call a function from within a condition, 'set -e' gets deactivated/doesn't work.
For illustration, take a look at the following example:
Output: Probably not what you would have expected. Not using 'set -e' is no good solution either, so, for the time being, I still use it, but I am still looking for a better solution.[1] https://www.in-ulm.de/~mascheck/various/set-e/