Menu

#69 Improve error message quality: type names, etc.

2.3.21
closed-fixed
nobody
None
5
2014-10-16
2010-03-24
Anonymous
No

I get an error in a macro where I am trying to compare an int value from Spring controller with a number.

1) [#if crntPage == 1] gives me the following error

The only legal comparisons are between two numbers, two strings, or two dates.
Left hand operand is a freemarker.template.SimpleScalar
Right hand operand is a freemarker.template.SimpleNumber

2) and this seems to be in CONTRADICTION to [#if crntPage == "1"]

The only legal comparisons are between two numbers, two strings, or two dates.
Left hand operand is a freemarker.template."SimpleNumber"
Right hand operand is a freemarker.template.SimpleScalar

3) and [#if crntPage?number == 1] gives me the below error

Error: on line 62, column 14 in macros/navigation.ftl
Expecting a number here, found:
The problematic instruction:
----------
==> if crntPage?number == 1 [on line 62, column 9 in macros/navigation.ftl]
in user-directive navigation.pagination [on line 88, column 5 in admin-home.ftl]
in user-directive app.page [on line 1, column 1 in admin-home.ftl]
----------

Java backtrace for programmers:
----------
freemarker.core.NonNumericalException: Error: on line 62, column 14 in macros/navigation.ftl
Expecting a number here, found:
at freemarker.core.StringBuiltins$numberBI.calculateResult(StringBuiltins.java:187)
at freemarker.core.StringBuiltins$StringBuiltIn._getAsTemplateModel(StringBuiltins.java:71)
at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
at freemarker.core.ComparisonExpression.isTrue(ComparisonExpression.java:111)
at freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:77)
at freemarker.core.Environment.visit(Environment.java:208)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:208)
at freemarker.core.Macro$Context.runMacro(Macro.java:164)
at freemarker.core.Environment.visit(Environment.java:601)
at freemarker.core.UnifiedCall.accept(UnifiedCall.java:106)
at freemarker.core.Environment.visit(Environment.java:208)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:208)
at freemarker.core.Environment.visit(Environment.java:393)
at freemarker.core.BodyInstruction.accept(BodyInstruction.java:93)
at freemarker.core.Environment.visit(Environment.java:208)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:208)
at freemarker.core.Environment.visit(Environment.java:297)
at freemarker.core.BlockAssignment.accept(BlockAssignment.java:83)
at freemarker.core.Environment.visit(Environment.java:208)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:208)
at freemarker.core.Macro$Context.runMacro(Macro.java:164)
at freemarker.core.Environment.visit(Environment.java:601)
at freemarker.core.UnifiedCall.accept(UnifiedCall.java:106)
at freemarker.core.Environment.visit(Environment.java:208)
at freemarker.core.Environment.process(Environment.java:188)
at freemarker.template.Template.process(Template.java:237)
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:344)
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:280)
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:225)
at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:174)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:258)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1174)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:901)
at com.wsgc.ecommerce.mvc.dispatcher.ContentDispatcher.doDispatch(ContentDispatcher.java:91)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1124)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:359)
at org.springframework.security.securechannel.ChannelProcessingFilter.doFilterHttp(ChannelProcessingFilter.java:116)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:271)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
at com.wsgc.ecommerce.security.filters.WSISessionContextIntegrationFilter.doFilterHttp(WSISessionContextIntegrationFilter.java:219)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
at com.wsgc.ecommerce.security.filters.RequestContextSecurityFilter.doFilterHttp(RequestContextSecurityFilter.java:127)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:174)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:756)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:334)
at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:126)
at org.tuckey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:195)
at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:159)
at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:141)
at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:90)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:417)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:756)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:502)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:826)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:523)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:377)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at org.mortbay.jetty.security.SslSocketConnector$SslConnection.run(SslSocketConnector.java:635)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:497)

3) and

[#if crntPage == "1"?number] tells me

The only legal comparisons are between two numbers, two strings, or two dates.
Left hand operand is a freemarker.template.SimpleScalar
Right hand operand is a freemarker.template.SimpleNumber

and the only thing that seems to work for me is [#if crntPage?string == "1"]

I could not quickly find information in the documentation..... so checking here....

Discussion

  • Dániel Dékány

    I suspect that the problem is that the data-model is inconsistent regarding the type of crntPage. More specifically, from the crntPage?number error message it seems that crntPage is sometimes an empty string ("") instead of a number. If crntPage is always a number, [#if crntPage == 1] will work, I'm pretty sure.

     
  • Anonymous

    Anonymous - 2010-03-24
    Thanks. I checked that in the macro i received it as an empty string. That resolved the problem. But I still feel that the error messages were a bit misleading earlier...
    
     

    Last edit: Anonymous 2017-05-17
  • Dániel Dékány

    • summary: improper error message when trying to compare numbers --> Improve error message qulaity: type names, etc.
     
  • Dániel Dékány

    The over error message quality should be better for sure... Like string values in error messages should always be quoted. Also "SimpleScalar" doesn't tell much to anybody but FM experts. Anyway, I change this to an RFE then, with changed title.

     
  • Dániel Dékány

    • summary: Improve error message qulaity: type names, etc. --> Improve error message quality: type names, etc.
     
  • Dániel Dékány

    2.3.21 (and 2.3.20) has improved type error message understandability significantly.

     
  • Dániel Dékány

    • status: open --> closed-fixed
    • Group: --> 2.3.21
     

Log in to post a comment.