thymeleaf-spring icon indicating copy to clipboard operation
thymeleaf-spring copied to clipboard

TemplateProcessingException not keeping line & col information

Open rmelian opened this issue 6 years ago • 1 comments

spring_boot_version=2.0.4.RELEASE org.springframework.boot:spring-boot-starter-thymeleaf:2.0.3 org.thymeleaf:thymeleaf:3.0.9 org.thymeleaf:thymeleaf-spring5:3.0.9

I'm using thymeleaf with spring and I have the case when an exception is thrown because of an error like this one:

org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'RunTime' cannot be found on object of type 'java.util.LinkedHashMap' - maybe not public or not valid?

here the issue is I'm trying to bind a property 'RunTime' that doesn't exists in the context, so far so good.

Now i want to capture a org.thymeleaf.exceptions.TemplateProcessingException to get the detail of the error like line and col but these(line & col) are lost in the chain of Exceptions:

Here is a stacktrace when thymeleaf throws a TemplateProcessingException from method evaluate in SPELVariableExpressionEvaluator:

image

then method processDefaultAttribute from class StandardDefaultAttributesTagProcessor will capture it and re-throw it again: you can see in the image line and col numbers

image

then method parseDocument from class MarkupParser will capture it and throw a ParseException

image

you can see line and col are there. Now the issue is happening in the constructor of ParseException:

`public ParseException(final Throwable throwable) {

    super(message(null, throwable), throwable);
    
    if (throwable != null && throwable instanceof ParseException) {
        this.line = ((ParseException)throwable).getLine();
        this.col = ((ParseException)throwable).getCol();
    } else {
        this.line = null;
        this.col = null;
    }
    
}`

as you can see here to keep line & col is expecting a subtype of ParseException but the exception is of type org.thymeleaf.exceptions.TemplateProcessingException which doesn't share the ParseException interface image

so in this case line and col numbers should be kept on ParseException as a way to be captured in the exception chain down the road

rmelian avatar Aug 23 '18 21:08 rmelian

Note this can only happen when Thymeleaf is being executed with the template cache disabled, as it is the only way it can happen that the parser (AttoParser) actually drives the execution of the template. Unfortunately, this setup is commonly used in development and it is then when these errors are more important, so we should try to devise some kind of solution.

The key issue here is ParseException is not a Thymeleaf class, but AttoParser's. And AttoParser of course cannot have a dependency on Thymeleaf so the ParseException class cannot directly get line and col from TemplateProcessingException in its constructor. Maybe we could do something from the adapter at the Thymeleaf side as it should be informed (separately) by AttoParser's APIs of the location, then set it manually into the ParseException...

danielfernandez avatar Oct 31 '18 00:10 danielfernandez