【问题标题】:Freemarker Template Attempt/Recover error is not logged in freemarker.runtime.attemptFreemarker 模板尝试/恢复错误未记录在 freemarker.runtime.attempt
【发布时间】:2014-09-19 15:23:36
【问题描述】:

我有以下代码:

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

我们的想法是在可用时使用自定义模板,或者在不可用时使用默认模板。据我了解,在尝试/恢复块内生成的所有错误都将记录为:freemarker.runtime.attempt 根据this page,但似乎不是,或者似乎不是这种情况.

记录模板处理期间抛出的模板异常,但被尝试/恢复指令捕获。启用 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

我怎样才能让它不会产生严重的错误?

【问题讨论】:

  • Documentation says: "模板执行期间发生的错误总是被记录下来,即使它们发生在尝试块内。"
  • 请查看this page - 尽管始终记录所有错误,但尝试/恢复错误记录为 freemarker.runtime.attempt 并且应该在调试时可用。

标签: java freemarker


【解决方案1】:

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

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

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

【讨论】:

  • 您的逻辑取决于丢失的文件。我试图做的是将逻辑保持在前端级别。我会重新考虑这个方法,看看我是否能以不同的方式获得类似的结果。
猜你喜欢
  • 2017-09-15
  • 2015-02-27
  • 2016-07-07
  • 2017-01-15
  • 2011-01-08
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多