Forum Discussion

FICO's avatar
FICO
Community Manager
14 years ago

Evaluation error: unexpected value: null

Evaluation error: unexpected value: null

We are using a Java-BOM with quite complex objects.

When the objects are filled not necessarilly all properties are filled and these properties can themselves be complex classes as well.

So for example we have:

A damagedItem of type DamagedItem

which could contain a vehicle property of type Vehicle

which contains a make property of type String

A condition on the make would look like:

if (damagedItem.vehicle.make = "Ford") then ...

But if vehicle is not filled i.e. is null you get an "Evaluation error: unexpected value: null" on the vehicle.

So some posts suggest to add guard clauses like:

if (damagedItem is not null

and damagedItem.vehicle is not null

and damagedItem.vehicle.make = "Ford") then ...

But these conditions are build through an RMA and I don't want the business analist to have to enter these guard clauses.

So we build the following template:

if truethen { print("in rule"); try {  print("in try");  validConditions = true;  <Loop over conditionListVH>  if(validConditions)  then {   validConditions = (<conditionListVH>);  }  <End Loop>   } catch an Exception with {  print("in catch");   validConditions = false; } if (validConditions) then {  print ("it fired"); }};

 which generates the following code:

if truethen { print("in rule"); try {  print("in try");  validConditions = true;  if(validConditions)  then {   validConditions = (claimRTBundle.claimRT.valueObject.causeType.type is equal to "200");  }  if(validConditions)  then {   validConditions = (claimRTBundle.damagedItemRT.valueObject.vehicle.make is equal to "Ford");  }   } catch an Exception with {  print("in catch");   validConditions = false; } if (validConditions) then {  print ("it fired"); }};

- How is the rest of you coping with these kind of issues?

- Is there another/easier way to prevent these Evaluation errors?

- Are there any downsides to the solution I have now, like Blaze optimalization not working anymore at some point, because we are screwing up the Rete algoritm or something?

Niek

7 Replies

  • FICO's avatar
    FICO
    Community Manager

    Hi Niek,

         I'm guessing that in the SRL portion of your original rule you coded something like this:

       if (damagedItem.vehicle.make = <makeVH> ) then ... 

        I have to admit, I am too much of a Java beginner to even follow your code attempt but, Yes, it does negate RETE because all conditions will be  "if (true)".  So, I would first suggest that you try:

        if ( damagedItem.vehicle.make is not null  and

              damagedItem.vehicle.make = <makeVH> ) then ....

        If any part of the path is null then this will fail.  There is no need to test each piece individually.  This will be coded as part of your template, the RMA will not show the null test code.  It "happens behind the scene" to save your users the trouble.

         Tom Sheckells

         Business Rules Consulting, Inc. 

  • FICO's avatar
    FICO
    Community Manager

    Have you tried the code you suggest when there is no vehicle instance?

    Because we have and like I said it gives an Evaluation error.

    Blaze/Java can not evaluate the make of the vehicle if there is no vehicle.

    And that's what I want to solve.

  • FICO's avatar
    FICO
    Community Manager

    Hi NK,

    You can avoid null evaluation error by following checks:

    1. Do a 'null' check for the 2 propoerty you are using in the rules : 'causeType.type' and 'vehicle.make'

    2. Declaring 'validConditions' variable in a bigger scope i-e, outside of Try-Catch clause.

    Note1: Have stackTrace printed in the catch clause. Which givs you a better picture of the value being null.

    Thanks & Regards,

    >> SCH

  • FICO's avatar
    FICO
    Community Manager

    Hi Sandesh,

    1. The null check I know of, it's in my posted question

    2. Yes this is the case, the code works

    Note1: It's not about solving 1 error, its about a solution for the nullable objects.

    Niek

  • FICO's avatar
    FICO
    Community Manager

    OK, then the next attempt is

            if (damagedItem.vehicle is available and 

                damagedItem.vehicle.make is not null  and

                damagedItem.vehicle.make = <makeVH> ) then ....

    This should take care of the issue when the vehicle does not exist.

         Tom Sheckells

         Business Rules Consulting, Inc.

  • FICO's avatar
    FICO
    Community Manager

    Hi Tasmot,

    Yes, like I said in my previous posts, I'm aware of the possibility of adding guard clauses:

    "

    So some posts suggest to add guard clauses like:

    if (damagedItem is not null

    and damagedItem.vehicle is not null

    and damagedItem.vehicle.make = "Ford") then ...

    "

    But if my template goes 4 levels deep because of the complex object model then generating these guard clauses can (to my opinion) only be achieved by a custom provider which is quit complex. Like in your example you need to work with available/known on the top-level and not null on the rest and stuff like that.

    So the question was:

    What's the easy way?

    I'm beginning to think there isn't one  (http://blaze.i.lithium.com/i/smilies/16x16_smiley-sad.gif) (http://blaze.i.lithium.com/i/smilies/16x16_smiley-frustrated.gif)

  • FICO's avatar
    FICO
    Community Manager

    Hi Niek,

         I need to level set to understand what you are trying to accomplish.  My understanding was that you wanted to retain the benefit of RETE, so not have that very complicated "if (true)" template code,  and not have RMA coding guard clauses.

         My suggestion of the multilayer "if" condition is a way to code the guard clauses in the template (so that RMA users are not even aware of them), the clauses will correctly allow RETE to operate, and the RMA users will just make selections in the RMA and the template will contain the proper guard clauses which will prevent exceptions. 

         My assumption is that the RMA users are creating rules that will operate on all the potential instances.  One thought is to add a pattern to the ruleset and code a quantified expression on the pattern that only passes elements with the necessary properties present.  That expression can have the necessary qualifications "such that damagedItem.vehicle is available" so that the individual rules are simpler.

         Tom Sheckells

         Business Rules Consulting, Inc.