如何在 eXist-db 的模板中显示错误日志,而不是在它之外?

How to show error log in a template in eXist-db, not outside of it?

在我的控制器中:

else if (ends-with($exist:resource, ".html")) then
    (: the html page is run through view.xql to expand templates :)
     <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
        <view>
            <forward url="{$exist:controller}/modules/view.xql">
                <set-header name="Cache-Control" value="no-cache"/>
            </forward>
        </view>
        <error-handler>
            <forward url="{$exist:controller}/error-page.html" method="get"/>
            <forward url="{$exist:controller}/modules/view.xql"/>
        </error-handler>
    </dispatch>

通常,这在模板函数失败时会有所帮助(例如 <div class="app:list-journals"/>)。如何将其用于后台失败的任何功能(例如,在提交表单后)?

更新

这是我试图捕获模板函数错误的代码:

 ...
 } catch * {
       <error>Error {$err:code}: {$err:description}</error>
 }

这不起作用。该应用程序仍然使用自己的日志作为裸 XML 响应。

或者我希望这样:

...
} catch * {
    logger:add-log-message(concat('Error: ', $err:code, $err:description))
}

... 可以使用一些重定向到全局错误页面,但它不能。只要错误不是应用程序的问题,而是 XSLT 进程的问题,就不可能将应用程序重定向到 A. Retter 书中描述的某个全局页面(必须使用 $EXIST_HOME/webapp/WEB-INF/web.xml 文件并在那里描述错误和重定向的特定页面)。

更多信息,无进展。

嗯,这道题比较笨拙,答案不得不说有点繁琐。问题是我不知道关于错误的几件事以及它们与 XQuery 和 eXist 模板模块的关系。

表面上看来我基本上可以处理三个级别的错误:

1 — 与模板相关的错误 这些错误最容易解决。在你的控制器中定义一个错误处理程序就足够了 URL 重写(一般或特定页面):

else if (ends-with($exist:resource, ".html")) then
     <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
        <view>
            <forward url="{$exist:controller}/modules/view.xql">
                <set-header name="Cache-Control" value="no-cache"/>
            </forward>
        </view>
        <error-handler>
            <forward url="{$exist:controller}/error-page.html" method="get"/>
            <forward url="{$exist:controller}/modules/view.xql"/>
        </error-handler>
    </dispatch>

如果与模板关联的任何功能失败,日志将显示在一个框架内,它看起来像您的应用程序页面的公共部分:

2 — 与通过 Jetty 的某些特殊 HTTP 代码相关的错误

这些错误由 Jetty 记录——页面消失,取而代之的通常是很长的日志。可以在 $EXIST_HOME/webapp/WEB-INF/web.xml:

中记录此类错误
<error-page>
    <error-code>404</error-code>
    <location>/db/central/page404.xq</location>
</error-page>

从逻辑上讲,location 应该指向应用内的真实页面。我们不能忘记它在 controller.xql:

中的定义
else if ($exist:path eq 'error-404.html') then
    <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
        <forward url="{$exist:controller}/errors/error-404.html"/>
        <view>
            <forward url="{$exist:controller}/modules/view.xql">
                <set-header name="Cache-Control" value="no-cache"/>
            </forward>
        </view>
    </dispatch>

如果您知道要使用户更友好地重复出现错误,则此解决方案很有用。非常适合 HTTP 404HTTP 500 错误。 HTTP 500 错误是最大的问题,因为它们与函数 运行 产生的错误有关。很好的解决方案。

3 — 其余

在 XQuery 中,有 several types of errors。对于 dynamic 错误(在运行时抛出并被 Jetty 记录为 HTTP 500 错误)可以使用 try/catch 语句。使用它们,可以捕获日志并将它们存储在您的应用程序中的某个位置。如果你在2号里像我一样对待他们就够了。其他类型的错误(从我的角度来看)更难捕捉(静态错误、类型错误等)。这意味着没有简单的方法可以为用户隐藏它们。无论如何,加号是您通常在原型设计和测试期间更早地了解它们。

也许有一些复杂的可能性以友好的方式显示 所有 错误,但这超出了 space 和本论坛的时间。灵感来自 Demo apps。这样的解决方案可能有点耗时,目前有点人为的问题。

非常感谢任何澄清和争论。