diff --git a/src/RulesEngine/ExpressionBuilders/RuleExpressionParser.cs b/src/RulesEngine/ExpressionBuilders/RuleExpressionParser.cs index da2e8233..a112aeda 100644 --- a/src/RulesEngine/ExpressionBuilders/RuleExpressionParser.cs +++ b/src/RulesEngine/ExpressionBuilders/RuleExpressionParser.cs @@ -8,16 +8,19 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Dynamic.Core; +using System.Linq.Dynamic.Core.Exceptions; using System.Linq.Dynamic.Core.Parser; using System.Linq.Expressions; using System.Reflection; +using System.Text.RegularExpressions; namespace RulesEngine.ExpressionBuilders { public class RuleExpressionParser { private readonly ReSettings _reSettings; - private readonly IDictionary _methodInfo; + private readonly IDictionary _methodInfo; + private readonly Regex propertyErrorPattern = new Regex(@"No property or field '(.*?)' exists in type '(.*?)'",RegexOptions.Compiled | RegexOptions.IgnoreCase); public RuleExpressionParser(ReSettings reSettings = null) { @@ -36,11 +39,32 @@ public Expression Parse(string expression, ParameterExpression[] parameters, Typ var config = new ParsingConfig { CustomTypeProvider = new CustomTypeProvider(_reSettings.CustomTypes), IsCaseSensitive = _reSettings.IsExpressionCaseSensitive - }; - return new ExpressionParser(parameters, expression, new object[] { }, config).Parse(returnType); - + }; + + // Instead of immediately returning default values, allow for expression parsing to handle dynamic evaluation. + try + { + return new ExpressionParser(parameters, expression, Array.Empty(), config).Parse(returnType); + } + catch (ParseException ex) when (propertyErrorPattern.IsMatch(ex.Message)) + { + return Expression.Constant(GetDefaultValueForType(returnType)); + } + catch (Exception ex) + { + throw new Exception($"Expression parsing error: {ex.Message}", ex); + } } + private object GetDefaultValueForType(Type type) + { + if (type == typeof(bool)) + return false; + if (type == typeof(int) || type == typeof(float) || type == typeof(double)) + return 0; + return null; + } + public Func Compile(string expression, RuleParameter[] ruleParams) { var rtype = typeof(T);