As I mentioned above, captureValue implicitly invokes setState(NORMAL), so this was another option for working around the underlying issue.
That wiki page is imprecise -- it's not caused by an ASH function returning false, it's when it leaves Mafia in an error state. Plenty of user-defined functions return false without aborting execution, and ditto with built-in ("library") functions (have_skill() and boolean_modifier(), to list a couple that never do).
Note: Your patch does not affect the behavior of boolean-returning ASH functions called from JS code--they still throw instead of returning false
. Changing this is not a high priority for me, though.
That was not the intention of the patch.
I think we fix this by making sure `.captureValue()` is run on every function call in JS
I don't agree with this.
Yes, you may dislike this behavior. But it's effectively an alternative for ASH's lack of robust exception handling. JS does have actual exceptions, so we have the option to throw some form of Exception, instead.
Now, if JavaScript had something like C++17's [[nodiscard]], then I'd suggest the use of that for the relevant ASH functions and continue on our way (so if you want to ignore exceptions, then you need to do that very explicitly, and if they fail, that's on you). But we don't. If we have a script that uses the bare
JavaScript:
eat(1, Item.get("fortune cookie"));
as part of a sequence of commands when hunting for semirares, should we just proceed with the rest of the script as if nothing happened? Adventure in the wrong location?
"That's on the script writer!" you might insist. "If it's intended to be used as a precondition, well, there's a return value for a reason. Even in a Bash script, if a single line fails, it'll keep going unless it explicitly calls exit."
Here's the thing, though: there are multiple kinds of reasons why that above line can fail. The underlying retrieveItem could fail (not enough meat, NPC store not available). One or more underlying requests to the server could time out, generating an IOException. You could have incidentally queued up a consumption helper like a salad fork, and not had enough HP to survive. What if it's part of a broader sequence of actions?
JavaScript:
eat(1, SALAD_FORK);
eat(1, EXTRA_GREASY_SLIDER);
useSkill(1, COCOON);
chew(1, INSTANT_KARMA);
adventure(1, NOOB_CAVE); // get pantsgiving fullness
eat(1, FORTUNE_COOKIE);
We don't have support for this level of nuance in ASH (wherein we can only capture that there was an error), but, in JS, we can do better. Some errors can be retried (after careful inspection of state to check whether the request actually made it to and was processed by the server); others cannot.
</rant>