Open jpco opened 10 months ago
A thought that has just occurred to me, relevant for exception-based exit-on-false: Should false-exiting commands also cause an exception inside an exception handler? For example, if the following script is sourced with -e
, should "finished the handler" be echoed or not?
catch @ e {
result maybe throw an error here?
echo finished the handler
} {
result throw an error here
}
Regarding your last suggestion, i would expect anything inside an exception handler that results in a false value to throw another exception when -e
is in use.
This would be expected behavior to me, but it certainly makes writing an exception handler more difficult when -e
is used, particularly because catch @ {false} {result foo}
will still trigger a false exception.
I haven't encountered any trouble yet, but why does a false
exception cause the shell to exit in %interactive-loop
?
In fact, the only exceptions caught by %interactive-loop
that should cause the shell to exit should be the exit
and eof
exceptions, so calling %dispatch
after catching an error
exception is wrong too...
I can understand abandoning further evaluation and the shell complaining about the exception, but there's no need for an interactive session to die just because something went wrong is there?
%batch-loop
should exit if an exception is uncaught, but not %interactive-loop
, right?
Or am i missing something glaringly obvious as usual? :-P
This would be expected behavior to me, but it certainly makes writing an exception handler more difficult when -e is used, particularly because catch @ {false} {result foo} will still trigger a false exception.
Yikes. Though I suppose that things like
; result = <={catch @ {false} {result foo}}
still work? This feels to me like a tradeoff between "more-surprising and more-useful" behavior and "less-surprising and less-useful" behavior. It's hard for me to judge the tradeoff without some actual experience. So I guess initially I'd say let's go with the less-surprising behavior, and if it ends up burdensome in practice, it can be revisited later.
Or am i missing something glaringly obvious as usual? :-P
You're missing nothing at all, and I actually prefer a complain-and-retry behavior in %interactive-loop
for false results, and I initially implemented it that way -- but I got nervous about the idea of changing the "exit on false" flag to not actually cause the shell to, well, exit on false, so I changed it in a4f3b6d93afee2e47faca2f5df995c6f39ec10db. I'd happily revert that commit, though.
so calling %dispatch after catching an error exception is wrong too...
I only just got this (somehow I don't remember reading it at all before). You're 100% right, I missed that case. Though now that I look at it, I'm not entirely sure what the point of the $fn-%dispatch false
line is in its current form, so I'm not sure exactly what the right behavior should be. Is it just there to make sure a shell invoked with -e
will die on an error
exception?
This pull request is meant to improve the usefulness of es'
-e
flag. It does a few things:This makes it so that exits-on-false only occur when
$&exitonfalse
is actually in the call stack. With this, REPL code, and functions called from the REPL like%parse
or%write-history
, can't cause the shell to implode, and so are much easier to write.result <={var = value}
).The implementation seems a little sketchy to me, but as far as I have been able to test, it works. Before this PR, every one of the following lines causes the shell to exit; with it, none of them do.
Instead of just calling
exit(2)
, throw afalse
exception along with the triggering value. I strongly feel that using an exception is the Right Thing:most other ways to cause the shell to exit do so via exceptions -- including the
exit
command itself! It is unpleasantly surprising to lack the ability to handle and clean up after errors just for this.exit-on-false is essentially a crappy imitation of exceptions in shells that lack them. Es actually has exceptions, so it should use them for this like it does for internal errors, signals, and the like. Exceptions are a far more powerful mechanism for error handling than just killing the process.
I picked
false
because it seems more useful to have a novel exception rather than re-using an existing one.I would rename
%exit-on-false
and$&exitonfalse
to%throw-on-false
and$&throwonfalse
if not for maintaining backwards compatibility.If the user doesn't go out of their way catch
false
in a script, then the shell will quietly exit. In an interactive context...%interactive-loop
catches thefalse
exception, complains, and then re-prompts.This is a fair bit friendlier than silently exiting -- not that it's very typical to use
-e
for an interactive session.