microsoft / microsoft/RulesEngine

Optional parameters for method calls not supported by expression evaluation

Open
#623 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
4.4k
Forks
616
Avg merge
6m
Merged PRs (30d)
2

Description

STR

Define a rule as following:

{
      "RuleName": "TestPdfAttachmentContent1",
      "Expression": "pdfAttachments[0].PdfContentContainsSubstring(\"Mahnung\")"
}

(That input/RuleParameter is of course defined, it's not what matters here.)

If I catch all CLR exceptions while debugging, I get the following exception:

RulesEngine.Exceptions.RuleException
  HResult=0x80131500
  Nachricht = Error while compiling rule `TestPdfAttachmentContent1`: No applicable method 'PdfContentContainsSubstring' exists in type 'PdfAttachmentValidator'
  Quelle = RulesEngine
  Stapelüberwachung:
   bei RulesEngine.HelperFunctions.Helpers.HandleRuleException(Exception ex, Rule rule, ReSettings reSettings)

  Diese Ausnahme wurde ursprünglich von dieser Aufrufliste ausgelöst:
    RulesEngine.HelperFunctions.Helpers.HandleRuleException(System.Exception, RulesEngine.Models.Rule, RulesEngine.Models.ReSettings)
    RulesEngine.ExpressionBuilders.LambdaExpressionBuilder.BuildDelegateForRule(RulesEngine.Models.Rule, RulesEngine.Models.RuleParameter[])
    RulesEngine.RuleCompiler.BuildRuleFunc(RulesEngine.Models.Rule, RulesEngine.Models.RuleParameter[])
    RulesEngine.RuleCompiler.GetDelegateForRule(RulesEngine.Models.Rule, RulesEngine.Models.RuleParameter[])
    RulesEngine.RuleCompiler.CompileRule(RulesEngine.Models.Rule, RulesEngine.Models.RuleExpressionType, RulesEngine.Models.RuleParameter[], System.Lazy<RulesEngine.Models.RuleExpressionParameter[]>)

Innere Ausnahme 1:
ParseException: No applicable method 'PdfContentContainsSubstring' exists in type 'PdfAttachmentValidator'

Not, however, and this is a general behavior I don't quite like the exception is silently ignored even though I have explicitly disabled EnableExceptionAsErrorMessage (see below).

Note this is not true, because the PdfAttachmentValidator has such a method, but with an optional second argument:

public class PdfAttachmentValidator
{
    public bool PdfContentContainsSubstring(string substring, bool caseInsensitive = true)
    {
        return true;
    }
}

And yes, I've obviously injected the type:

      var engineSettings = new ReSettings()
        {
            CustomActions = // ...
            CustomTypes =
            [
                typeof(PdfAttachmentValidator)
            ],
            EnableExceptionAsErrorMessage = false
        };
     
        new RulesEngine.RulesEngine(mailWorkflows, engineSettings);
What happens

Apparently, it cannot find PdfContentContainsSubstring("Mahnung") as it cannot find the method signature PdfContentContainsSubstring(string substring, bool caseInsensitive = true).

What should happen

Just call PdfContentContainsSubstring with PdfContentContainsSubstring("Mahnung"), ignoring the optional parameter.

Workaround

Changing it like this and passing the optional parameter explicitly, makes it magically work:

{
      "RuleName": "TestPdfAttachmentContent1",
      "Expression": "pdfAttachments[0].PdfContentContainsSubstring(\"Mahnung\", true)"
}

But this is superfluous, obviously. And I would like to avoid this for obvious reasons.

More information

Weirdly enough, even changing it to default does not work (for whatever reason):

{
      "RuleName": "TestPdfAttachmentContent1",
      "Expression": "pdfAttachments[0].PdfContentContainsSubstring(\"Mahnung\", default)"
}

The (handled) exception then is Unknown identifier 'default':

RulesEngine.Exceptions.RuleException
  HResult=0x80131500
  Nachricht = Error while compiling rule `TestPdfAttachmentContent1`: Unknown identifier 'default'
  Quelle = RulesEngine
  Stapelüberwachung:
   bei RulesEngine.HelperFunctions.Helpers.HandleRuleException(Exception ex, Rule rule, ReSettings reSettings)
   bei RulesEngine.HelperFunctions.Helpers.ToRuleExceptionResult(ReSettings reSettings, Rule rule, Exception ex)
   bei RulesEngine.RuleCompiler.CompileRule(Rule rule, RuleExpressionType ruleExpressionType, RuleParameter[] ruleParams, Lazy`1 globalParams)
   bei RulesEngine.RulesEngine.CompileRule(Rule rule, RuleExpressionType ruleExpressionType, RuleParameter[] ruleParams, Lazy`1 scopedParams)
   bei RulesEngine.RulesEngine.CompileRule(String workflowName, String ruleName, RuleParameter[] ruleParameters)
   bei RulesEngine.RulesEngine.<ExecuteActionWorkflowAsync>d__13.MoveNext()

  Diese Ausnahme wurde ursprünglich von dieser Aufrufliste ausgelöst:
    RulesEngine.HelperFunctions.Helpers.HandleRuleException(System.Exception, RulesEngine.Models.Rule, RulesEngine.Models.ReSettings)
    RulesEngine.ExpressionBuilders.LambdaExpressionBuilder.BuildDelegateForRule(RulesEngine.Models.Rule, RulesEngine.Models.RuleParameter[])
    RulesEngine.RuleCompiler.BuildRuleFunc(RulesEngine.Models.Rule, RulesEngine.Models.RuleParameter[])
    RulesEngine.RuleCompiler.GetDelegateForRule(RulesEngine.Models.Rule, RulesEngine.Models.RuleParameter[])
    RulesEngine.RuleCompiler.CompileRule(RulesEngine.Models.Rule, RulesEngine.Models.RuleExpressionType, RulesEngine.Models.RuleParameter[], System.Lazy<RulesEngine.Models.RuleExpressionParameter[]>)

Innere Ausnahme 1:
ParseException: Unknown identifier 'default'

System

    <TargetFramework>net8.0</TargetFramework>
<!-- ... -->
    <PackageReference Include="RulesEngine" Version="5.0.3" /> 

aka .NET 8

Windows 10

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the expression with PdfAttachmentValidator and an omitted optional argument, then inspect LambdaExpressionBuilder.BuildDelegateForRule and the RuleCompiler entry points named in the stack trace. Done means the expression compiles and invokes PdfContentContainsSubstring("Mahnung") without explicitly passing the optional parameter, with regression coverage for this case.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.