On this page
attempt, recover
Page Contents
Synopsis
<#attempt>
attempt block
<#recover>
recover block
</#attempt>
Where:
attempt block
:包含任何内容的模板块。这将始终执行,但是如果在此期间发生错误,则该块的所有输出都将回滚,并且将执行recover block
。recover block
:包含任何内容的模板块。仅在执行attempt block
时发生错误时才执行此操作。您可以在此处等打印错误信息。
recover
是必填项。 attempt
/recover
可以自由嵌套到其他attempt block
或recover block
内。
Note:
从 2.3.3 开始,支持此处显示的格式;较早的版本是<#attempt>...<#recover>...</#recover>
,仍支持向后兼容。此外,这些指令是在 FreeMarker 2.3.1 中引入的,因此在 2.3 中不存在。
Description
如果您希望页面成功输出,即使页面某部分的输出失败,也可以使用这些指令。如果在执行attempt block
时发生错误,则回退attempt block
的输出(并记录错误,至少使用默认配置),然后执行recover block
,然后在recover block
之后正常 continue 执行模板。如果在执行attempt block
的过程中未发生错误,则recover block
被忽略。一个简单的例子:
Primary content
<#attempt>
Optional content: ${thisMayFails}
<#recover>
Ops! The optional content is not available.
</#attempt>
Primary content continued
如果thisMayFails
变量不存在(或在该位置发生任何其他错误),则输出为:
Primary content
Ops! The optional content is not available.
Primary content continued
如果thisMayFails
变量存在并且其值为123
,则输出为:
Primary content
Optional content: 123
Primary content continued
attempt block
具有全有或全无的语义:要么输出attempt block
的全部内容(没有错误时),要么从执行attempt block
的结果根本没有输出(当有错误时)。例如,在上面,失败发生在打印了“可选内容:”之后,但在“操作!”之前的输出中仍然没有出现。 (这是通过在attempt block
内部积极地缓冲输出来实现的.甚至flush
指令都不会将输出发送到 Client 端.)
为了避免上面的示例造成误解:attempt
/recover
不(仅)用于处理未定义的变量(为此使用缺少值处理程序运算符)。它可以处理执行该块时发生的所有类型的错误(即不是语法错误,这是较早发现的)。它的意思是封装更大的模板片段,在这些片段上可能会出现错误。例如,您的模板中有一部分处理印刷广告,但这不是页面的主要内容,因此您不希望整个页面都掉下来是因为印刷广告时会发生一些错误(例如,因为数据库服务器中断)。因此,您将整个广告打印都放在attempt block
中。
在某些环境下,程序员对 FreeMarker 进行了配置,以使其不会因某些错误而中止模板执行,而是 continue 执行(可能在向输出输出一些错误指示符之后再执行)(请参阅here...)。 attempt
指令不将抑制的错误视为错误。
在recover block
内部,该错误的错误消息可用于error
special variable。不要忘记对特殊变量的引用以点开头(例如:${.error}
)。
默认情况下,attempt block
内部发生的错误是ERROR
级的logged,尽管模板已从中恢复。这是因为attempt
并不是通用错误处理程序机制,就像try
在 Java 中一样。这是为了减少意外错误对访问者的影响,它可以使页面的仅一部分下降而不是整个页面下降。但这仍然是一个错误,需要操作员注意。 (从 FreeMarker 2.3.27 开始,可以使用attempt_exception_reporter
配置设置自定义报告此错误的方式.)