Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhances the exception message displayed #841

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 107 additions & 2 deletions dotnet/src/dotnetframework/GxClasses/Helpers/GXMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace GeneXus.Metadata
#endif
using GeneXus.Application;
using System.Collections.Concurrent;
using System.Text;

public class ClassLoader
{
Expand Down Expand Up @@ -267,15 +268,18 @@ static public void ExecuteVoidRef(object o, string mthd, Object[] args)
pm[0] = ((pi.Attributes & ParameterAttributes.In) != ParameterAttributes.None);
pm[1] = ((pi.Attributes & ParameterAttributes.Out) != ParameterAttributes.None);
pm[2] = pi.ParameterType.IsByRef;
pms[i] = pm;
if (i < pms.Length)
{
pms[i] = pm;
}
}
try
{
o.GetType().InvokeMember(mthd, BindingFlags.InvokeMethod, null, o, args, pms, null, null);

}catch(MissingMethodException)
{
throw new GxClassLoaderException("Method " + mi.DeclaringType.FullName + "." + mi.Name + " for " + args.Length + " parameters ("+ String.Join(",", args) + ") not found");
throw new GxClassLoaderException(BuildParameterMismatchErrorMessage(mi.DeclaringType.FullName, pis, args));
}
}
else
Expand All @@ -292,6 +296,107 @@ static public void ExecuteVoidRef(object o, string mthd, Object[] args)
throw GxClassLoaderException.ProcessException(e);
}
}
static string BuildParameterMismatchErrorMessage(string objectName, ParameterInfo[] methodParameters, object[] runtimeMethodParameters)
{
string parmInfo = GetParameterTypesString(methodParameters);
string runtimeParms = GetParameterValuesString(runtimeMethodParameters);
StringBuilder errorMessage = new StringBuilder();
if (methodParameters.Length == 0)
{
errorMessage.Append($"The object {objectName} does not have any parameters, thus it does not match the ");
}
else if (methodParameters.Length == 1)
{
errorMessage.Append($"The parm rule of {objectName} with parameter: {parmInfo} does not match the ");
}
else
{
errorMessage.Append($"The parm rule of {objectName} with parameters: {parmInfo} does not match the ");
}

if (runtimeMethodParameters.Length == 0)
{
errorMessage.Append($"absence of values provided at runtime. ");
}
else if (runtimeMethodParameters.Length == 1)
{
errorMessage.Append($"value provided in runtime: {runtimeParms}. ");
}
else
{
errorMessage.Append($"values provided in runtime: {runtimeParms}. ");
}
errorMessage.Append($"Please check the parm rule of the {objectName}.");

return errorMessage.ToString();
}

static string GetParameterValuesString(object[] runtimeMethodParameters)
{
StringBuilder sb = new StringBuilder();
sb.Append('(');

for (int i = 0; i < runtimeMethodParameters.Length; i++)
{
object parmValue = runtimeMethodParameters[i];
string parmStringValue = (parmValue is string) ? $"\"{parmValue}\"" : parmValue.ToString();
sb.Append(parmStringValue);
if (i < runtimeMethodParameters.Length - 1)
{
sb.Append(", ");
}
}
sb.Append(')');
return sb.ToString();
}

static string GetParameterTypesString(ParameterInfo[] parameters)
{
StringBuilder sb = new StringBuilder();
sb.Append('(');

for (int i = 0; i < parameters.Length; i++)
{
string parmTypeName = ParameterTypeName(parameters[i].ParameterType);
sb.Append(parmTypeName);
if (i < parameters.Length - 1)
{
sb.Append(", ");
}
}
sb.Append(')');
return sb.ToString();
}

static string ParameterTypeName(Type parameterType)
{
Type innerType = (parameterType.IsByRef && parameterType.GetElementType()!=null) ? parameterType.GetElementType() : parameterType;
if (IsNumericType(innerType))
return "Numeric";
return innerType.Name;
}

static bool IsNumericType(Type type)
{
if (type == typeof(byte) ||
type == typeof(sbyte) ||
type == typeof(short) ||
type == typeof(ushort) ||
type == typeof(int) ||
type == typeof(uint) ||
type == typeof(long) ||
type == typeof(ulong) ||
type == typeof(float) ||
type == typeof(double) ||
type == typeof(decimal))
{
return true;
}
else
{
return false;
}
}
static public void ExecuteRef(object o, string mthd, Object[] args)
{
GXLogging.Debug(log, "ExecuteRef '" + "class '" + o + "' mthd '" + mthd + "'");
Expand Down