1
votes

Our company is in the process of switching our template engine from Velocity to Thymeleaf. We use Splunk for our logging, and with Velocity we were able to implement org.apache.velocity.runtime.log.LogChute to handle custom logging (format for and log to our splunk log), but I have been unable to find any similar class for Thymeleaf.

I've tried a couple of approaches so far. First, I tried to extend the actual Thymeleaf engine and add a try/catch wrapper around the process method, but that method is final, unfortunately. I saw a suggestion to add a filter to catch the thymeleaf errors, but something must be swallowing the error, because it never reaches that catch block.

The only option I can think of at this point is to simply pull org.thymeleaf.TemplateEngine logs into our splunk log, but then it won't be properly formatted for ingestion and I can't add any custom fields.

Does anybody have any ideas?

EDIT:

Wow, so I just retried the Filter approach and it worked, but the caught exception was org.springframework.web.util.NestedServletException, so JRebel must not have reloaded my changes to catch Exception instead of TemplateEngineException when I tried it last.

That said, if anybody has a better approach, I'd love to hear it. I'm new to the whole question posting thing; should I post an answer?

1
Use Spring Integration Adapter check youtube.com/watch?v=oLoPpKq3JgU You can post your answer and accept it until a better answer is given - Sully

1 Answers

0
votes

The filter approach did end up working, but the TemplateEngineException is wrapped around by a NestedServletException.

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.web.util.NestedServletException;
import org.thymeleaf.exceptions.TemplateEngineException;

/**
 * Filter to catch Thymeleaf template errors
 */
public class ThymeleafErrorFilter implements Filter {

    @Override
    public void init(final FilterConfig filterConfig) {

    }

    @Override
    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } catch (final NestedServletException nse) {
            if(nse.getCause() instanceof TemplateEngineException) {
                //Do stuff here
                ...
            }

            throw nse;
        }
    }

    @Override
    public void destroy() {
    }
}

And then registering the filter

    /**
     * @return thymeleaf error filter
     */
    @Bean
    public FilterRegistrationBean thymeleafErrorFilter() {
        FilterRegistrationBean thymeleafErrorFilter = new FilterRegistrationBean();
        thymeleafErrorFilter.setName("thymeleafErrorFilter");
        thymeleafErrorFilter.setFilter(new ThymeleafErrorFilter());
        thymeleafErrorFilter.addUrlPatterns("/*");
        return thymeleafErrorFilter;
    }