Exception handling

Linknoid

Member
It would be nice if there were some way to handle exceptions for situations you know will generate an error. Trying to avoid a script stopping because of a known error is rather hackish and prone to breaking.

I have 3 examples of things that stop a script when I don't want it to:

1. Counters expiring when visiting adventure.php
2. Equipping a custom outfit when you don't have all the items currently. I use outfits to reduce the number of server hits for changing equipment, so if switching to a different outfit is 2 or more pieces of gear closer to my goal outfit, I can save some calls to equip(). So it doesn't really matter if 100% of the outfit is available.
3. Equipment breaking at the end of combat (like garbage shirt).

I get around #1 with this hack:

Code:
    void BypassCounterError()
    {
        // This is just an invalid URL to trigger the semi-rare warning so we can get past it, without crashing this
        // script, so it won't actually take a turn unless it happens to trigger a counter script:
        boolean ignore = cli_execute("try; visit_url adventure.php?snarfblat=99999999");
    }

I used to get around #2 by calling visit_url() instead of outfit(), but I just discovered it no longer works:

Code:
                int outfitNum = outfitsByNumber[bestMatch];
                print("wearing outfit #" + outfitNum);
                string url = "inv_equip.php?action=outfit&which=2&whichoutfit=-" + outfitNum;
                string ignore = visit_url(url);
		//boolean ignore = cli_execute("try; visit_url " + url);

I tried changing it to use the cli_execute("try; ...") line that is comment out, but that just prints the HTML page to the log and then stops the script anyway.

#3 I haven't figured out how to work around that at all, other than I guess unequipping the item the turn it will break.


There's already a try/finally block, why not a try/catch? Since the errors don't really have a type, it would probably make the most sense to catch based on a string pattern (maybe regex?) I can understand not wanting the script to blindly keep running no matter what happens (like if you hit an Ultrarare, that's not something you want a script ignoring), but there should be some way to tell Mafia, "I expect this specific error to occur, and I will deal with it in my script".
 
For #1, you can use the counters cli command to turn off the interupt. My afterAdventure.ash uses cli_execute("counters nowarn Fortune Cookie") before it tries for a semirare.

You can get around #2 by using cli_execute("/outfit bla"), if the outfit is valid for the chat command (either a real outfit, or a custom one within KoL), that way, it will use KoLs own outfit equipping methods, and thus, equip parts of outfits as much as possible.

And for #3, you want to set breakableHandling9699 to something other than the default 1 (which is to abort on breakage). Breakable equipment in general is handled by the breakableHandling setting, which can be set in the choice adventures dropdown, but the individual equipment overrides are hidden, so yeah, you just have to know that that's a thing. https://i.imgur.com/hMqEfRD.png , https://i.imgur.com/vEf5ONL.png
 
Last edited:

Linknoid

Member
Looks like the cli_execute("/outfit ...") works correctly. It's kind of surprising that the command line version goes without error, but the outfit() ash function fails. I guess I'd expect them to work the same, or a script function to be more reliable than a command line call.

The other stuff requires changing global properties. Even if you put a try/finally to reset the property to its old value, there's still no guarantee it will get reset to its original value. I've had scripts get stuck to the point where only exiting the whole application can get it to break out of where it's stuck (related to internet connection issues). I suppose I could write the original value to a backup file before changing it, and then check for the backup file at the startup of each script. Making stuff reliable just seems to get more and more convoluted, compared to just catching a specific error when it occurs.
 

ckb

Minion
Staff member
Another option for #1 would be to create a counterScript. See example here.

This should give you control of doing whatever you want (or nothing) when counters expire.
 
Top