Skip to content

Create a $&throwonfalse primitive and false exception handling#280

Open
jpco wants to merge 2 commits into
wryun:masterfrom
jpco:throwonfalse2
Open

Create a $&throwonfalse primitive and false exception handling#280
jpco wants to merge 2 commits into
wryun:masterfrom
jpco:throwonfalse2

Conversation

@jpco
Copy link
Copy Markdown
Collaborator

@jpco jpco commented May 25, 2026

This primitive is intended to supplant $&exitonfalse. When using $&throwonfalse, the shell will raise a false exception if a command produces a falsey result. The argument to the false exception is the value which triggered it. false is caught by $&if (for commands which are run as tests) and by the <= construct.

For example, echo <={result first; result second} with $&throwonfalse will print first, as the result first will cause a false first exception to be raised, which will then be caught by the <={} and used as if it were a normal result.

Using exceptions to implement the -e flag is really the Right Thing:

  1. Running cleanup code after a false result in an es -e script is impossible today, which is a really bad limitation of the -e flag. Other shells have something like rc's sigexit, or bash's trap EXIT, to perform cleanup in this case, but es doesn't use traps for dealing with interruptions: it uses exceptions.

  2. Exceptions allow more flexible handling than the signal/exit/error traps of other shells. For example, using es -e interactively is totally reasonable with an %interactive-loop which catches and handles false. Moreover, the behavior is flexible: you could have it quietly treat the exception like any other result (the default), you could have it catch and print any false results, or you could have it make the interactive shell abruptly exit, if for some strange reason you wanted a more "traditional" experience.

  3. Using exceptions allows us to avoid the traditional warts of the -e flag. In other shells (and in es today) commands within if or while tests are run with the -e behavior dynamically disabled. This causes enough inconsistency and unpredictability in what is supposed to be a "safety" mechanism that many people recommend avoiding using -e at all. However, with exceptions, and with an if and <= which catch the exception to use the value, we avoid any need to conditionally disable the behavior. (On top of this, es' more complete return values from pipes mean that the pipefail option isn't necessary or useful at all.)

I am proposing this behind a #define as an alternative to $&exitonfalse for now because I have already iterated a fair bit on the design of the false exception up to this point, and I want to make sure it really gets hammered out before it becomes the Official, Documented, and Only Behavior.

This primitive is intended to replace $&exitonfalse, but its behavior
isn't quite sorted out yet.  Because of this, we're leaving it
undocumented and unused by default for now.

Using exceptions to implement the -e flag is the Right Thing.
@jpco jpco changed the title Create a $&throwonfalse primitive and 'false' exception handling Create a $&throwonfalse primitive and false exception handling May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant