Freemarker.runtime.attempt中未记录Freemarker模板尝试/恢复错误

时间:2014-09-19 15:23:37

标签: java freemarker

我有以下代码:

<#attempt>
    <#include "brands/custom.ftl">
<#recover>
    <#include "brands/default.ftl">
</#attempt>

我们的想法是在可用时提供自定义模板,或者在默认情况下使用自定义模板。据我所知,在try / recover块中生成的所有错误都将记录为:freemarker.runtime.attempt,符合this page,但它似乎没有,或者它似乎不是案子。

  

记录模板处理期间抛出的模板异常,但是被try / recover指令捕获。启用DEBUG严重性以查看异常。

对我来说,它会产生以下错误:

freemarker.log.JDK14LoggerFactory$JDK14Logger error
SEVERE: Template processing error: "Error reading included file brands/custom.ftl"

Error reading included file brands/custom.ftl
The problematic instruction:
----------
==> include "brands/custom.ftl" [on line 5, column 9 in _header.ftl]
 in include "_header.ftl" [on line 2, column 1 in index.ftl]
----------

Java backtrace for programmers:
----------
freemarker.template.TemplateException: Error reading included file brands/custom.ftl
at freemarker.core.Include.accept(Include.java:167)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.Environment.visit(Environment.java:361)
at freemarker.core.AttemptBlock.accept(AttemptBlock.java:73)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.Environment.include(Environment.java:1508)
at freemarker.core.Include.accept(Include.java:169)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.Environment.process(Environment.java:199)
at freemarker.template.Template.process(Template.java:259)
at com.company.portal.http.Controller.processTemplate(Controller.java:586)
at com.company.portal.http.Controller.guardedService(Controller.java:354)
at com.company.portal.http.Controller.service(Controller.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at com.radiadesign.catalina.session.RedisSessionHandlerValve.invoke(RedisSessionHandlerValve.java:26)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.FileNotFoundException: Template brands/custom.ftl not found.
at freemarker.template.Configuration.getTemplate(Configuration.java:580)
at freemarker.core.Environment.getTemplateForInclusion(Environment.java:1490)
at freemarker.core.Include.accept(Include.java:157)
... 41 more

如何制作它以免产生严重错误?

1 个答案:

答案 0 :(得分:1)

#attempt / #recover文档说:“模板执行期间发生的错误始终会被记录,即使它们发生在尝试块中也是如此。” #recover捕获的异常记录在“[DEBUG] freemarker.runtime.attempt”下。也就是说,您无法使用#attempt / #recover进行正常的流量控制。它适用于灾难恢复,例如当某些事情发生故障但你不想让整个页面失败时,只需显示一些错误指示并继续。但您仍然希望提醒系统管理员或获取错误日志的人。

至于你想要实现的目标,没有内置的指令。但是,在2.3.21 API(还没有... GitHub 2.3或2.3-gae head)中,Environment有一个Template getTemplateForInclusion(String name, String encoding, boolean parse, boolean ignoreMissing)方法 - 请注意最后一个参数。如果此方法返回非null,则可以继续include(Template),否则您可以尝试获取另一个模板。您可以使用TemplateDirectiveModel实现自定义指令。

顺便说一下,你确定这个逻辑是合理的吗?不能只是应用程序告诉模板要包含的模板的名称是什么? (我不喜欢,如果一个逻辑依赖于一个文件丢失。如果它偶然丢失,甚至因为一个错字而丢失了什么?现在模板不会失败告诉你,只是退回并包含其他内容静默。)