GWT - 无法使用 UncaughtExceptionHandler 捕获 StatusCodeException

GWT - Unable to catch StatusCodeException with UncaughtExceptionHandler

当 Tomcat 会话超时时,我想将我的用户重定向到我的 GWT 应用程序的主页,以便他们可以再次登录。为了强制执行此操作,我尝试使用 GWT 在用户会话超时后尝试执行任何操作时抛出的 StatusCodeException -

SEVERE: com.google.gwt.user.client.rpc.StatusCodeException: 0  

为此,我使用了以下代码 -

public void onModuleLoad() {
    GWT.UncaughtExceptionHandler uncaughtExceptionHandler = new GWT.UncaughtExceptionHandler() {
        public void onUncaughtException(Throwable e) {
            if (e instanceof StatusCodeException) {
                logger.log(Level.ERROR, "Exception caught!");
                logger.log(Level.ERROR, ((StatusCodeException) e).getStatusCode());
            }
        }
    };
    GWT.setUncaughtExceptionHandler(uncaughtExceptionHandler);
    try {
        // rest of the code in onModule() - I'm expecting any operation to throw StatusCodeException when session times out.
    } catch (RuntimeException ex) {
        uncaughtExceptionHandler.onUncaughtException(ex);
    }
}

这是行不通的。 StatusCodeException 没有被代码捕获,而是显示在控制台上。我在这里做错了什么?

想法是捕获 StatusCodeException 并使用其 getStatusCode() 方法找出 HTTP 错误代码是否为 403。如果是,我想使用 Window.Location.assign("https://example.com/redirect"); 将他们重定向到登录页面。

   onFailure(Throwable caught) { 
       logger.error(caught); 
   }

您的 AsyncCallback.onFailure 完全按照您的要求执行 - 它记录错误,但不抛出错误。因为它没有被抛出,所以未捕获的异常处理程序不会处理它(它不能被捕获,如果它没有被抛出......如果这有意义的话)。

一个选项可能是您可以使用 throw caught 填充该方法,但 java 不喜欢这样。相反,最简单的答案就是将它传递给处理程序:

   onFailure(Throwable caught) { 
       GWT.getUncaughtExceptionHandler().onUncaughtException(ex);
   }

您还有一个选择:因为没有 AsyncCallback 会抛出这个,将 StatusCodeException 放在 UncaughtExceptionHandler 中似乎有点奇怪。相反,请考虑创建自己的 AsyncCallback 基础 class,如下所示:

public abstract class NetworkAsyncCallback<T> implements AsyncCallback<T> {
    @Override
    public void onFailure(Throwable t) {
        if (e instanceof StatusCodeException) {
            logger.log(Level.ERROR, "Exception caught!");
            logger.log(Level.ERROR, ((StatusCodeException) e).getStatusCode());
        }
    }
}

现在,当你调用时,你只需要传入一个新的NetworkAsyncCallback<T>并且只实现onSuccess。如果它要做的只是将异常传递给未捕获的处理程序,则可以跳过 onFailure。或者,如果您有一些其他逻辑,您可以覆盖 onFailure,处理适当的异常,并调用 super.onFailure(caught) 处理任何其他错误,以便 superclass 处理它。

myServer.getSomeData(param, new NetworkAsyncCallback<Result>() {
    @Override
    public void onSuccess(Result result) {
        //...
    }
    // Skip onFailure, or if you need custom logic, implement it, 
    // and call super only if the exception isn't part of that logic
});