{"record":{"id":"30f64b4ea60d5821","repo":"Tencent/APIJSON","slug":"function-n-key-value","errorCode":null,"errorMessage":"字符 \" + function + \" 对应的远程函数传参类型错误！\\n请检查 key:value 中value的类型是否满足已定义的函数 \" + getFunction(fb.getMethod(), fb.getKeys()) + \" 的要求！\" + (Log.DEBUG ? e.getMessage() : \"\")","messagePattern":"字符 \" \\+ function \\+ \" 对应的远程函数传参类型错误！\\\\n请检查 key:value 中value的类型是否满足已定义的函数 \" \\+ getFunction\\(fb\\.getMethod\\(\\), fb\\.getKeys\\(\\)\\) \\+ \" 的要求！\" \\+ \\(Log\\.DEBUG \\? e\\.getMessage\\(\\) : \"\"\\)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java","lineNumber":458,"sourceCode":"\n\t\ttry {\n            return invoke(parser, fb.getMethod(), fb.getTypes(), fb.getValues(), (String) row.get(\"returnType\"), current, SCRIPT_EXECUTOR_MAP.get(lang));\n\t\t}\n        catch (Exception e) {\n\t\t\tif (e instanceof NoSuchMethodException) {\n\t\t\t\tthrow new IllegalArgumentException(\"字符 \" + function + \" 对应的远程函数 \" + getFunction(fb.getMethod(), fb.getKeys())\n                        + \" 不在后端 \" + parser.getClass().getName() + \" 内，也不在父类中！如果需要则先新增对应方法！\"\n\t\t\t\t\t\t+ \"\\n请检查函数名和参数数量是否与已定义的函数一致！\"\n\t\t\t\t\t\t+ \"\\n且必须为 function(key0,key1,...) 这种单函数格式！\"\n\t\t\t\t\t\t+ \"\\nfunction 必须符合 Java 函数命名，key 是用于在 curObj 内取值的键！\"\n\t\t\t\t\t\t+ \"\\n调用时不要有空格！\" + (Log.DEBUG ? e.getMessage() : \"\"));\n\t\t\t}\n\t\t\tif (e instanceof InvocationTargetException) {\n\t\t\t\tThrowable te = ((InvocationTargetException) e).getTargetException();\n\t\t\t\tif (StringUtil.isEmpty(te.getMessage(), true) == false) { //到处把函数声明throws Exception改成throws Throwable挺麻烦\n\t\t\t\t\tthrow te instanceof Exception ? (Exception) te : new Exception(te.getMessage());\n\t\t\t\t}\n\t\t\t\tthrow new IllegalArgumentException(\"字符 \" + function + \" 对应的远程函数传参类型错误！\"\n\t\t\t\t\t\t+ \"\\n请检查 key:value 中value的类型是否满足已定义的函数 \" + getFunction(fb.getMethod(), fb.getKeys()) + \" 的要求！\"\n\t\t\t\t\t\t+ (Log.DEBUG ? e.getMessage() : \"\"));\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\n\t}\n\n\t/**反射调用\n     * @param parser\n     * @param methodName\n     * @param parameterTypes\n     * @param args\n     * @return {@link #invoke(AbstractFunctionParser, String, Class[], Object[])}\n     * @throws Exception\n     */\n\t@SuppressWarnings({\"unchecked\", \"rawtypes\"})\n\tpublic static <T, M extends Map<String, Object>, L extends List<Object>> Object invoke(","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java#L440-L476","documentation":"The reflective call reached a real method but java.lang.reflect.InvocationTargetException fired and the underlying target exception had no message (common for NullPointerException/ClassCastException inside the function or for mismatched argument types). APIJSON cannot rethrow an informative exception, so it reports a parameter-type error and reminds you that each key's value type must satisfy the method signature.","triggerScenarios":"Function arguments resolved from the request have runtime types that fail inside the method (e.g. String passed where Long expected causing ClassCastException, or a null key causing NPE) and the target exception message is empty.","commonSituations":"Request omits a key so the method receives null; JSON numbers deserialize as Integer while the method expects Long; string vs number confusion for id fields.","solutions":["Check each key:value pair in the function call against the Java method's parameter types and fix the request values.","Ensure referenced keys exist in the current object so arguments are not null.","Widen the Java method signature (e.g. accept Object or Number and convert internally) for tolerant parsing.","Turn on Log.DEBUG so e.getMessage() from the target exception is appended to this error for diagnosis."],"exampleFix":"// before: long id parameter, request sends string\n{\"@column\":\"enc(id)\"} // id = \"123\" -> fails\n\n// after\npublic Object enc(Object id) { long v = Long.parseLong(String.valueOf(id)); ... }","handlingStrategy":"validation","validationCode":"for (Object arg : resolvedArgs) {\n    if (arg == null) { /* referenced key missing in request: fail fast with key name */ }\n}\n// and compare each arg's class against the target method's parameter types before invoke","typeGuard":"public static boolean argsMatch(Method m, Object[] args) {\n    Class<?>[] p = m.getParameterTypes();\n    if (p.length != args.length) return false;\n    for (int i = 0; i < args.length; i++) { if (args[i] != null && !p[i].isInstance(args[i]) && !isWidening(args[i], p[i])) return false; }\n    return true;\n}","tryCatchPattern":"try { parser.invoke(fn, current); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"传参类型错误\")) { /* check key:value types vs method signature; enable Log.DEBUG for detail */ } throw e; }","preventionTips":["Type function parameters as Object or broad types and convert inside, since JSON deserialization yields Integer/Long/String variability.","Always ensure keys referenced in function expressions exist in the request object.","Run dev with Log.DEBUG=true so the underlying cause is appended."],"tags":["apijson","remote-function","argument-type","reflection"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}