3

キャッチされていないすべての例外をフレームワークでキャッチし、適切な通知メッセージを表示する必要があります。

したがって、UI に次のようなカスタムを設定しErrorHandlerました (「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) すると、Tomcat の一般的な例外ハンドラーから知っているような例外ビューが表示されます。

を設定したのは間違っていErrorHandlerますか?より良い方法はありますか?

Glassfish 4 と Vaadin 7 を使用しています。

4

1 に答える 1

5

また、Glassfish 4 と Vaadin 7 も使用します。次のように、独自のカスタマイズされた ErrorHandler (インターフェースを実装する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());
    }

    ...
}
于 2013-12-17T07:42:25.247 に答える