I am trying to parse errorCode like
4011=Error thrown expected: {0} found: {1}.
using Message.format in kotlin
loggingService.logTheMsg("4011", arrayOf("${expectedVal}", "${actualVal}"))
In logTheMsg I am using this code :
var errorMessage = props.getProperty(errorCode)
errorMessage = MessageFormat.format(errorMessage as String, args)
println("${errorMessage}.")
but getting output as :
Error thrown expected:[Ljava.lang.String;#38f3b4ba found: {1}.
It might help in answering , the same thing is achieved in java like this:
parse(value, new String[]{"firstName","lastName"});
And in parse:
parse(String value, String[]args) {
value = MessageFormat.format((String) value, args);
System.out.println(value);
}
prints:
my name is firstName lastName
To remove ambiguity, Kotlin requires 'spread operator' (*) on array which is going to be passed as vararg, i. e.
loggingService.logTheMsg("4011", *arrayOf("${expectedVal}", "${actualVal}"))
Also, "${expectedVal}" should be replaced with expectedVal:
loggingService.logTheMsg("4011", *arrayOf(expectedVal, actualVal))
And, of course, you can use varargs as they intended to be used:
loggingService.logTheMsg("4011", expectedVal, actualVal)
Related
I am trying to adopt existing code of parameter validation from Javalin 3 to Javalin 4. It uses Javalin's Validator class. Here's the code I've got (rewritten):
val messageId = ctx.pathParamAsClass<String>("messageId")
.check(check = { it.trim().matches(Uuid.REGEX) }, errorMessage = "message id must be a UUID")
.get()
.trim()
And I am getting compile error for the check() call:
e:
/home/ivan/.../SourceFile.kt: (53, 6): None of the following functions can be called with the arguments
supplied:
public final fun check(check: Check<String> /* = (String) -> Boolean */, error: ValidationError<String>):
Validator<String> defined in io.javalin.core.validation.Validator
public final fun check(check: Check<String> /* = (String) -> Boolean */, error: String): Validator<String> defined in
io.javalin.core.validation.Validator
I can't understand why there is an error. I assume I should have matched second overload of check(). How to write it correctly?
Note: I have read Javalin 3 to 4 migration guide, which gives example like this:
ctx.queryParamAsClass<Int>("age")
.check({ it >= 18 }, ValidationError("AGE_TOO_LOW", args = mapOf("minAge" to 18)))
.get()
which I seem to follow, except I give it error message as string, but there's matching overload. So what is wrong here?
The cause was that second parameter of check() is called error, not errorMessage, i.e. correct code is like this:
...
.check(check = { it.trim().matches(Uuid.REGEX) }, error = "...")
...
I tried to initialize a property, though CodeBlock#of throws an IllegalArgumentException in CodeBlock#argToType
I looked into the root cause of the error which was at CodeBlock#argToType.
Even if o is a ClassName(which also is a TypeName) it does not pass the is TypeName -> o check and throws the IllegalArguementException.
val initString = "mutableMapOf(Pair(%T, %T), Pair(%T, %T))"
val initArgs = arraysOf(...)
CodeBlock.of(initString, initArgs)
I expected the CodeBlock to be built correctly, but instead it throws the IllegalArguementException
I reproduced you problem and was able to fix it; I think the key question is how you pass initArgs to CodeBlock.of: this method is expecting a second varargs parameter but you're passing a single Array<...> value.
Changing you code as follows seems to work:
fun main(args: Array<String>) {
val initString = "mutableMapOf(Pair(%T, %T), Pair(%T, %T))"
val initArgs = arrayOf(String::class.java, String::class.java, String::class.java, String::class.java)
val result = CodeBlock.of(initString, *initArgs)
println("result is $result")
}
The key point is to pass *initArgs, and not initArgs, as second parameter of CodeBlock.of.
I explicitly initialized initArgs' values witch type values, in order to match %T placeholder expectations.
I hope this can help you!
When I try to evaluate an expression I get this error: net.sourceforge.jeval.EvaluationException: Invalid use of quotes.
To be clearer. I read my rules from a .txt files where after I put them in a hasmap.
I have tried:
#{mentor} = Chung
#{mentor} = "Chung"
#{mentor} == "Chung"
#{mentor} == 'Chung'
but still gives another error or same error.
What am I doing wrong?
List<String> approvalMentors = new ArrayList<>();
Evaluator evaluator = new Evaluator();
evaluator.putVariable("mentor", String.valueOf(graduationApprovalRequest.getMentor()));
for (HashMap.Entry<String, String> entry : this.schoolRules.entrySet()) {
try {
if(evaluator.evaluate(entry.getValue()).equals("1.0")){
approvalMentors.add(entry.getKey());
}
} catch (EvaluationException ex) {
Logger.getLogger(SchoolRules.class.getName()).log(Level.SEVERE, null, ex);
}
}
return approvalMentors;
.txt File I read my rules from
#{mentor} = 'Chung'
JEval internal validation logic assumes each "operand" (a part of the conditional expression) should be either a built-in function, a number, a special symbol, OR a quoted string. If there is even a single SPACE between the == and double-quote symbols, the check for correctness of quoted string fails. Each such operand should either begin AND end with a quote(s), or do not have the quote(s) at all. The latter is the case with numbers, for example.
When executing the following piece of code:
def xml = new XmlSlurper().parse(url)
title = rss.chanel.title
rss.channel.item.each {
sql.firstRow("SELECT COUNT(*) FROM news WHERE title = ? ", [it.title])
}
I get the following error:
Invalid argument value: java.io.NotSerializableException
What may cause it?
The problem was that it.title was a NodeChild object.
In order to get the serializable text of this object I had to use it.title.text(). It was quite tricky since I could use print it.title successfully
numberrange returns [String value]
: numberrangesub
{
String numberRange = ($numberrangesub.text);
String [] v = numberRange.split(",");
if ( Integer.parseInt(v[0].trim()) < Integer.parseInt(v[1].trim())) $value =numberRange;
else throw new RecognitionException();
}
;
Please observe the above ANTLR code. In this I want to throw a user friendly error message like "from value should be less than to value in BETWEEN clause".
I am expecting like this RecognitionException("from value should be less than to value in BETWEEN clause"); But antlr did not accept like as above.
In java class where I am calling the generated java class by Antlr. I am handling like as follows.
try
{
parser.numberRangeCheck();
}
catch (RecognitionException e)
{
throw createException("Invalid Business logic syntax at " + parser.getErrorHeader(e) + ", " + parser.getErrorMessage(e, null), Level.INFO, logger);
}
Any help will be appriciated.
Why not simply throw a RuntimeException with your custom error message?
// ...
else throw new RuntimeException("from value should be less than to value in BETWEEN clause");
// ...
As Terrance wrote in "The Definitive ANTLR Reference" error chapter excerpt:
To avoid forcing English-only error messages and to generally make
things as flexible as possible, the recognizer does not create exception
objects with string messages. Instead, it tracks the information necessary to generate an error.
So there is no error message supplied to RecognitionError's constructor. But you can define additional field of your recognizer to hold user-friendly error message shown on RecognitionError handling:
numberrange returns [String value]
: numberrangesub
{
String numberRange = ($numberrangesub.text);
String [] v = numberRange.split(",");
if ( Integer.parseInt(v[0].trim()) < Integer.parseInt(v[1].trim()))
$value = numberRange;
else {
this.errorMessage = "from value should be less than to value in BETWEEN clause";
throw new RecognitionException(this.input);
}
}
;
And then override the getErrorMessage method:
public String getErrorMessage(RecognitionException e, String[] tokenNames) {
String msg = this.errorMessage;
// ...
}
This works similar to paraphrase mechanism explained in the same excerpt.