In Bash blocks {} and subshells () the exit early doesn't work if there is an OR condition following it. Take for example
set -e
{ echo a; false; echo b; } || echo c 
prints
a
b
and
set -e
{ echo a; false; echo b; false;} || echo c 
prints
a
b
c
It seems to take the last executed command's exit code only. While this makes sense, given a semicolon instead of && is used, I'd expect the set -e to still make it exit on the first false and execute the error handling echo c code.
Using && instead of ; does make it work, but that makes it messy when having multiple line blocks. Adding in set -e at the start of the block/subshell also has no effect.
The reason this confuses me is because
set -e
{ echo a; false; echo b; }
prints
a
which means the exit-on-failure works when there's no || code following it. So I'd expect this to be the case with || code following it, executing it after the first failure in the block. Is there no way to achieve that without appending && after each line in the block?

set -ein conditionals; or else a simpleif false; then echo foo; else echo bar; fiwould kill the script{ false; echo x; } && echo y;, the exit status offalseisn't exactly checked by any conditional (sinceecho xruns unconditionally after the semicolon), but it's still under the left-hand side of the&&soset -edoesn't kick in. It works similarly even if there's subshells or functions in between.set -e, test manually and be happier. :)set -eup until now.true && {false; something}behaving differently than{false; something} && trueunderset -eis a fantastic illustration of why to avoid it. You try to avoid the "unchecked error happened" case, but invite a complete host of corner cases not covered in a sensible way by the design of whatset -edoes.