bug: Beanshell Expression "<" issue in Layer trait

Vassal v3.4.2
Mac OS Catalina

I am finding what I think are spurious errors related to using the Less-Than (<) character in Beanshell expressions, perhaps particular to the Layer trait and, I guess, relating to HTML work.

Example: This expression used in the “Follow Expression” field of a Layer Trait:
{Status_Level<4 ? (gblSolo==true? 16:1) : (GetProperty(“gbl” +CombatActiveSide + “ArmyIndex”) + (CombatActiveSide==“Allies” ? 3 : 10))}

This expression seems to work fine, the various possible inputs give the expected Layer results. However, when the field is edited or when “Refresh Counters” is used on a pre-set scenario, the following error is generated. Note how the “<” character has been dropped from the copy of the expression in the error message:-

  • Bad Data in Module: [Layer - CombatActive] - Expression evaluation error followProperty[{Status_Level4 ? (gblSolo==true? 16:1) : (GetProperty(“gbl” +CombatActiveSide + “ArmyIndex”) + (CombatActiveSide==“Allies” ? 3 : 10))}]

When I substitute an equivalent condition for “Status_Level<4” - one that does not use “<” - the error goes away.

Have I missed something or is this a bug ?

One item I will make a note of is that the “Bad Module Data” message is being displayed through the HTML processor without having its < text corrected.

But that is a display error with the message, does not explain why message is happening in first place.

Brent will have to comment on the deeper mysteries of Beanshell, but the gblSolo==true not having “true” be in quotes is possibly suspicious (And would also explain why message went away if you changed the < sign in a way that changed which part the ? was being evaluated).

Possibly the gblSolo==true is an old-style thing that is “supposed to still be legacy-supported” and I’m not sure where Brent stands with that in terms of 3.4.2/3.4.3 – I remember some of that kind of stuff coming through the pipeline recently. So possibly 3.4.3 will get that part back to working again without change.

If It helps, I prefer to use booleans without (logically) unnecessary operators ; so I originally had the gblSolo part of the expression as “(gblSolo ? 16:1)” and it was giving the same error. Also, I make a lot of use of true and false as well as properties on their own as boolean, always without quotes and without problems… so hope that is ok. I am less confident that using a property on its own as a boolean is supported but it usually seems to work.

Hi Mark,

Do you have a log or save where this can be easily reproduced? I will have a look. Both "(gblSolo ? 16:1) and (gblSolo==true? 16:1) should work as well as (gblSolo==“true”? 16:1).

I’ve had a thought about how to dump more debugging info into the Error Log when Beanshell evaluation fails. With a bit of work, I may be able to dump out the value used for each variable when the expression failed. I would simplify the message in the Chatter to something like

‘Bad Data in Module: Beanshell evaluation failed in trait[Layer - CombatActive]. See Error Log for Details’.

The the error log would show something like

Beanshell expression failed
Source: Layer CombatActive
Expression: {Status_Level4 ? (gblSolo==true? 16:1) : (GetProperty(“gbl” +CombatActiveSide + “ArmyIndex”) + (CombatActiveSide==“Allies” ? 3 : 10))}
Status_Level4=true
gblSolo=false
CombatActiveSide=Allies

I have it on my list to improve the reporting for Beanshell failures, but this is the first decent idea I’ve had. Thoughts?

Regards.

Hi Brent -

I certainly like the idea of the failure mini-dump that you suggest. It would be a great short-cut to the inevitable debug reporting that a module developer has to start with when getting an error that isn’t immediately obvious to fix. Would it be too cumbersome or undesirable to have the details output direct to the chat window as well as the error log ?

I think it will be a save-file you need from me, as this error has only been occurring as a module loads or is refreshed… or maybe I can refresh to a log file (I will try that). I will follow this up shortly.

Whilst one the subject of Beanshell error messages, I have sometimes noticed that the “source” part of the current error message isn’t right - something I started noticing in v3.4.x if I remember rightly.

Mark

My concern with dumping a ton of debug info straight into the Chat Window is that it is not a good experience for a user who really doesn’t want to see all that if the module they are using goes bung. I’m looking into the possibility of a preference setting that a developer could use that would copy everything going to the log file to the Chatter as well.

Would these be Property Match Expressions in GKC’s that contain $$ variables? Like {Army="$Army"}? The problem with these is that by the time they are sent to BeanShell to be evaluated, the $$ variables have long since been replaced with values. I’ll have a look and see if I can improve this.

Thanks for the feedback.
Brent.

Hi Brent,

I don’t think $$ variables are the issue here and, in this case, GKCs are not involved.

I have a feeling that it is something to do with how boolean properties are being parsed in these expressions.

I have just been debugging a new series of “infinite loop” warnings from the piece in question - involving the layer and some text labels (I couldn’t see how a loop could result from setting a layer and text properties, when the rest of the module makes no reference to the properties that these traits can set).

The series of errors started occurring when I moved some common logic out of the text labels and into a Calculated Property, generating a boolean that I then tested in the labels. I am not sure how the Layer became involved but it is part of the same type of piece. A similar set of layer and labels is also in a another piece. The errors are, for each piece, 1 for the layer expression and one for each of the text labels plus another error which references the piece itself (see below).

Here’s the thing… of all the things I tried, nothing worked until I changed four expression components of the form "…&& xxxxHandOK ? … " to " “…&& xxxxHandOK==true ?..” - one in each of 2 of the labels in each of the 2 pieces. Immediately the errors stopped; refresh counters now works again without error.

Also, I might add that as with the original “layer” expression issue that I reported in this thread, regardless of these error messages, the functions were working fine and giving the expected results across the state changes that the booleans were testing for.

This was using Vassal VASSAL-3.4.4-SNAPSHOT-0c9d947ed.

Dump of the warning errors:-

[code]- Bad Data in Module: Possible infinite loop evaluating expression gblActiveSide==“Allies” || (gblIsCloseCombat==true && gblCombatPhase>1 && gblPhase==3) || gblConfigLocked==0 ? gblAlliesArmyIndex+3 : 1

  • Bad Data in Module: Possible infinite loop evaluating expression gblDeckChoice==1 && AlliesHandOK ? gblAlliesCommand:""
  • Bad Data in Module: Possible infinite loop evaluating expression gblDeckChoice==1 && AlliesHandOK!=true ? gblAlliesCmdCardsHeld:""
  • Bad Data in Module: Possible infinite loop evaluating expression gblDeckChoice!=1 && AlliesHandOK ? gblAlliesCommand:""
  • Bad Data in Module: side red R () () () [Text Label - Command Card Count (Green Deck-warning)] - Expression evaluation error {gblDeckChoice!=1 && AlliesHandOK ? gblAlliesCommand:""}
  • Bad Data in Module: Possible infinite loop evaluating expression gblDeckChoice!=1 && AlliesHandOK != true ? gblAlliesCmdCardsHeld:""
  • Bad Data in Module: Possible infinite loop evaluating expression gblActiveSide==“French” || (gblIsCloseCombat==true && gblCombatPhase>1 && gblPhase==3) || gblConfigLocked==0? gblFrenchArmyIndex+3 : 1
  • Bad Data in Module: Possible infinite loop evaluating expression gblDeckChoice==1 && FrenchHandOK ? gblFrenchCommand:""
  • Bad Data in Module: Possible infinite loop evaluating expression gblDeckChoice==1 && FrenchHandOK!=true ? gblFrenchCmdCardsHeld:""
  • Bad Data in Module: Possible infinite loop evaluating expression gblDeckChoice!=1 && FrenchHandOK ? gblFrenchCommand:""
  • Bad Data in Module: side blue L () () () [Text Label - Command Card Count (Green Deck-warning)] - Expression evaluation error {gblDeckChoice!=1 && FrenchHandOK ? gblFrenchCommand:""}
  • Bad Data in Module: Possible infinite loop evaluating expression gblDeckChoice!=1 && FrenchHandOK!=true ? gblFrenchCmdCardsHeld:""
    [/code]

Mark