vaadin - Vaadin 中的中央错误处理

标签 vaadin vaadin7

我希望框架捕获每个未捕获的异常并显示适当的通知消息。

因此我在我的 UI 中设置了一个自定义的 ErrorHandler(灵感来自“Book of Vaadin”:https://vaadin.com/book/-/page/application.errors.html):

public abstract class MyUI extends UI {

    @Override
    protected void init(final VaadinRequest request) {
        setErrorHandler(new DefaultErrorHandler() {
            @Override
            public void error(final com.vaadin.server.ErrorEvent event) {
                Throwable error = event.getThrowable();
                Notification.show(error.getLocalizedMessage(), Notification.Type.ERROR_MESSAGE);
            }
        });
    }
}

但是当我从后端加载时引发错误时它没有执行。相反,表单显示不完整,当我重新加载页面 (F5) 时,我得到了一个异常 View ,就像我从 Tomcat 的一般异常处理程序中了解到的那样。

是不是我设置的ErrorHandler有误?有没有更好的办法?

我正在使用 Glassfish 4 和 Vaadin 7。

最佳答案

我们还使用 Glassfish 4 和 Vaadin 7。 您可以像我们一样编写自己的自定义 ErrorHandler(它实现了接口(interface) com.vaadin.server.ErrorHandler):

@Override
public void error(ErrorEvent event) {
    // Finds the original source of the error/exception
    AbstractComponent component = DefaultErrorHandler.findAbstractComponent(event);
    if (component != null) {
        ErrorMessage errorMessage = getErrorMessageForException(event.getThrowable());
        if (errorMessage != null) {
            component.setComponentError(errorMessage);
            new Notification(null, errorMessage.getFormattedHtmlMessage(), Type.WARNING_MESSAGE, true).show(Page.getCurrent());
            return;
        }
    }
    DefaultErrorHandler.doDefault(event);
}

getErrorMessageForException 方法找出主要原因,这通常很有用:

private static ErrorMessage getErrorMessageForException(Throwable t) {

    PersistenceException persistenceException = getCauseOfType(t, PersistenceException.class);
    if (persistenceException != null) {
            return new UserError(persistenceException.getLocalizedMessage(), AbstractErrorMessage.ContentMode.TEXT, ErrorMessage.ErrorLevel.ERROR);
    }
    SQLException sqlException = getCauseOfType(t, SQLException.class);
    if (sqlException != null) {
        return new SQLErrorMessage(sqlException);
    }
    FieldGroup.CommitException commitException = getCauseOfType(t, FieldGroup.CommitException.class);
    if (commitException != null) {
        return new CommitErrorMessage(commitException);
    }
    EJBException eJBException = getCauseOfType(t, EJBException.class);
    if (eJBException != null) {
        return new UserError(eJBException.getLocalizedMessage(), AbstractErrorMessage.ContentMode.TEXT, ErrorMessage.ErrorLevel.ERROR);
    }
    ...
}

private static <T extends Throwable> T getCauseOfType(Throwable th, Class<T> type) {
    while (th != null) {
        if (type.isAssignableFrom(th.getClass())) {
            return (T) th;
        } else {
            th = th.getCause();
        }
    }
    return null;
}

希望这可以帮助您找到适合您的解决方案。

编辑:关于在何处设置 ErrorHandler 的问题和提示:

import com.vaadin.annotations.Theme;
import com.vaadin.cdi.CDIUI;
import com.vaadin.ui.UI;

@CDIUI
@Theme("abc")
public class CustomUI
        extends UI {
    ...

    @Override
    protected void init(VaadinRequest request) {
        ...
        // at main UI ...
        UI.getCurrent().setErrorHandler(new CustomErrorHandler());

        // ... or on session level
        VaadinSession.getCurrent().setErrorHandler(new CustomErrorHandler());
    }

    ...
}

关于vaadin - Vaadin 中的中央错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20615816/

相关文章:

java - Vaadin 8 网格布局删除行之间的多余空间

layout - Vaadin - 迭代布局中的组件

java - 在不使用 Maven 的情况下在 NetBeans 上使用 Vaadin

java - 如何在 Vaadin ComboBox 中使某个项目只能选择一次?

vaadin - 如何在 Vaadin 7 表中实现滚动监听器

java - 最有值(value)球员 : : Event Bus pattern instead of Listener

java - 如何在 vaadin 中定义 TextFields 的验证约束?

java - 如何获取当前 Vaadin 主题名称?

java - 有没有办法让 Vaadin 中的标题在不使用 FormLayout 的情况下出现在左侧?

java - Vaadin StringLengthValidator allowedNull 参数不起作用