[ 
https://issues.apache.org/jira/browse/CAMEL-24703?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18114638#comment-18114638
 ] 

Claus Ibsen commented on CAMEL-24703:
-------------------------------------

Implemented on local branch fix/CAMEL-24703 (two commits, not pushed yet), 
parse time and runtime:

camel-core-languages (SimpleSyntaxHints, used by both parsers and the function 
expression):
* body == 'x' -> "Unexpected token body: text outside ${...} is a literal, 
functions are written as ${body}, ${header.name}; did you mean ${body} == 'x'?"
* ${body == 'x'} and ${body.length() > 3} -> "Operators go outside the 
function: ${body} == 'x'" (an operator inside an open parenthesis, as in 
iif(...), is left alone)
* ${body} == x -> "Binary operator == does not accept x on the right hand side: 
write it as a quoted literal 'x', a number, true, false, null, or a function 
${...}, e.g. 'x'" (no more "token null")
* = / === / and / or / not / =!= -> "Unknown operator =: did you mean ==? 
Operators are ..." / "use && for and, and || for or"
* ${body} == 'x' || -> "Logical operator || needs a predicate on the right hand 
side, e.g. ${header.foo} == 'bar'"
* 'it''s' -> "... a literal that contains a single quote must be written with 
double quotes"
* ${header.foo -> "expected symbol functionEnd but was eol: missing } to close 
the function"
* Unknown function: padding(3) (did you mean ${pad(3)}?); ${property.foo} (did 
you mean ${exchangeProperty.foo}?); ${Body} (function names are case sensitive: 
${body}); ${ body } (remove the spaces); ${bodyxxx} (did you mean ${body}?) 
instead of "Valid syntax: ${body.OGNL}".

camel-bean:
* "Failed to invoke method: lenght() on null" -> "on the message body of type 
java.lang.String"
* MethodNotFoundException adds "(did you mean length()?)" from the bean's 
public method names.

The existing assertions that pinned the old wording (SimpleTest, 
FileLanguageTest, BeanParameterInvalidValueTest, CamelCatalogTest) were 
updated; the Simple parser, OGNL and catalog suites pass. Still open from the 
audit: ${body.toUpperCase} without parentheses (bean binding picks 
toUpperCase(Locale) and fails on the conversion, so the message is about 
java.util.Locale), and "No language could be found for: jsonpath" without the 
dependency hint.

> camel-core-languages - simple: error messages should say what to write (audit 
> against typical mistakes)
> -------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-24703
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24703
>             Project: Camel
>          Issue Type: Improvement
>          Components: camel-core
>            Reporter: Claus Ibsen
>            Priority: Major
>
> Every error message the Simple parser can produce was listed (about 60 throw 
> sites in core/camel-core-languages) and checked against 50 expressions a 
> local model typically writes in the AI authoring benchmark (2026-09-12). A 
> model recovers from a message that says what to write and loops on one that 
> only says what was wrong. The rendered form (message, "at location N", the 
> expression and the * marker) is good; the texts should name the fix. The main 
> cases:
> || model writes || today || proposed ||
> | body == 'Hello World' | Unexpected token b at location 0 | Unexpected token 
> 'b': text outside ${...} is a literal, functions are written as ${body}, 
> ${header.name}. Did you mean ${body} == 'Hello World'? |
> | ${body == 'x'} | Valid syntax: ${body.OGNL} was: body == 'x' | Operators go 
> outside the function: ${body} == 'x' |
> | ${body} == x | Binary operator == does not support token null | Binary 
> operator == needs a value on the right hand side: a quoted literal 'x', a 
> number, true, false, null, or a function ${...}; was: x (never print "token 
> null") |
> | ${body} = 'x' | Unexpected token = | Unknown operator '=': did you mean 
> '=='? Operators: ==, =~, !=, <, <=, >, >=, contains, !contains, ~~, regex, 
> in, !in, is, !is, range, !range, startsWith, endsWith |
> | ${body} == 'x' and ${header.y} == 1 | Unexpected token a | Unknown operator 
> 'and': use && for and, \|\| for or |
> | ${body} == 'x' \|\| | Logical operator \|\| does not support token null | 
> Logical operator \|\| needs a predicate on the right hand side |
> | ${body} == 'it''s' | expected symbol whiteSpace but was singleQuote | A 
> literal that contains a single quote must use double quotes: "it's" |
> | ${header.foo | expected symbol functionEnd but was eol | Missing } to close 
> ${header.foo |
> | ${padding(3)} | Unknown function: padding(3) | Unknown function 'padding': 
> did you mean pad(3)? (closest known name; the functions are listed on the 
> simple language functions page) |
> | ${upper(${body})} | Unknown function: upper(${body}) | as above, plus: a 
> nested ${...} inside a function argument is not supported |
> | ${property.foo} | Unknown function: property.foo | Unknown function 
> 'property': it is exchangeProperty.foo since Camel 3 (alias table for the 
> Camel 2 names) |
> | ${ body }, ${Body} | Unknown function:  body  / Body | remove the spaces / 
> functions are lower camel case: ${body} |
> | ${jsonpath($.name)} without the jar | No language could be found for: 
> jsonpath | add camel-jsonpath to the classpath 
> (org.apache.camel:camel-jsonpath) |
> | ${body.length() > 3} | runtime: Failed to invoke method: length() > 3 on 
> null due to: Method should end with parenthesis | Operators go outside the 
> function: ${body.length()} > 3 |
> | ${body.lenght()} | runtime: Failed to invoke method: lenght() on null due 
> to: MethodNotFoundException ... on bean: hello | drop the wrong "on null"; 
> Method lenght() not found on java.lang.String; did you mean length()? |
> | ${body.toUpperCase} | runtime: Failed to invoke method: toUpperCase on null 
> due to: CamelExecutionException: Exception occurred during execution | No 
> method or property toUpperCase on java.lang.String; a method call needs (): 
> ${body.toUpperCase()} |
> Accepted silently but not what was meant, where the eval tool and validator 
> can add a note: ${header.count} + 1 (Simple has no arithmetic, the + 1 is 
> text), ${body} ? 'a' : 'b' (no ? : operator; the elvis operator is ?: and a 
> conditional is iif(...)).
> Implementation notes: the parse time messages come from SimpleParserException 
> in BaseSimpleParser, SimplePredicateParser, SimpleExpressionParser, the ast 
> nodes and the function factories; "token null" has one origin per parser 
> (does not support token / has no left or right hand side token); the known 
> function names for suggestions are the BUILT_INS and EXPRESSION_ENTRIES in 
> SimpleFunctionDispatcher plus the fixed set; the catalog validator, camel 
> validate yaml, the TUI and the MCP tools all print these messages, so every 
> consumer benefits. The full audit with the probe program (SimpleProbe.java, 
> 50 cases) is kept with the benchmark material.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to