1

我基本上从通过 Primefaces AJAX 调用的 SQL 操作中得到了一些未捕获的异常。有趣的是,这个未捕获的异常在 FireBug 的 JavaScript 部分出现为错误:

<?xml 版本='1.0' 编码='UTF-8'?>
<partial-response><error><error-name>class javax.faces.el.E​​valuationException</error-name><error-message><![CDATA[事务回滚]]></error-message>< /error></partial-response>

并在带有所有堆栈跟踪和所有内容的 server.log 上。

但是如果不将它们重定向到单独的错误页面(并丢失所有输入数据),我无法将其引起用户注意。

处理此问题的正确方法是创建验证器,我会这样做,但总是有可能出现不知情的数据库问题,只会出现在执行 SQL 操作。所以我只谈论没有验证者的情况。

假设我有这个 JSF 片段。

    <h:form>
        <p:消息 />
        <..... primefaces (AJX) 一些按钮 .... action="bean.save()" />
    </h:form>

和 bean.save();

  公共无效保存()
  {
    尝试
    {
       em.merge(this.data);
    }
    捕获(异常 e)
    {
       // 即使由于某些破坏约束的原因无法合并数据,也从未在这里。
    }
  }

如果存在数据库错误,我们将在事务结束(AFTER save())之前看到它,所以我无法捕获它。(这通过调试演练得到证实,并且在此处添加“em.flush()”可以使整个工作正常进行)。

在左右看了之后,我创建了一个 PhaseListener 并且我能够得到异常。但是,我无法在 <p:messages /> 上显示该异常

    public void afterPhase(最终 PhaseEvent 事件)
    {
        final Iterable exceptionEvents = event.getFacesContext().getExceptionHandler().getUnhandledExceptionQueuedEvents();
        对于(最终的 ExceptionQueuedEvent 异常事件:异常事件)
        {
            // 这个打印出来(在 server.log 中找到)。
            System.out.println("问题:" + exceptionEvent.getContext().getException());
            // 但是这个消息没有。
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Problem", "Problem:" + exceptionEvent.getContext().getException()));
        }
    }

非常感谢任何建议。

4

1 回答 1

1

APhaseListener不是处理异常的正确位置。您应该使用ExceptionHandler. 您需要在代码中进行的唯一其他更改是您应该使用它Iterator来迭代异常并用于Iterator#remove()从队列中删除已处理的异常。否则,它仍将由默认异常处理程序以您所看到的 ajax 响应的形式处理。

也可以看看:

于 2012-08-16T22:18:10.793 回答