summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorLeif Åstrand <legioth@gmail.com>2018-10-02 14:21:41 +0300
committerSun Zhe <31067185+ZheSun88@users.noreply.github.com>2018-10-02 14:21:41 +0300
commit199bff6db17913501c049a7a456a1469af4fbfd2 (patch)
tree7f4b9c954dc68d9b02343df1e1db7596550c13dd /server
parent2c14aa2260495ec354bc1a5909318fd8b2edffc7 (diff)
downloadvaadin-framework-199bff6db17913501c049a7a456a1469af4fbfd2.tar.gz
vaadin-framework-199bff6db17913501c049a7a456a1469af4fbfd2.zip
Suppress unavoidable UIDetachedException (#11146)
* Suppress unavoidable UIDetachedException Fixes #11144
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/server/ErrorHandlingRunnable.java37
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinService.java8
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinSession.java7
-rw-r--r--server/src/main/java/com/vaadin/ui/UI.java44
4 files changed, 83 insertions, 13 deletions
diff --git a/server/src/main/java/com/vaadin/server/ErrorHandlingRunnable.java b/server/src/main/java/com/vaadin/server/ErrorHandlingRunnable.java
index 2066bfc9f1..a74c31c389 100644
--- a/server/src/main/java/com/vaadin/server/ErrorHandlingRunnable.java
+++ b/server/src/main/java/com/vaadin/server/ErrorHandlingRunnable.java
@@ -16,6 +16,7 @@
package com.vaadin.server;
import java.io.Serializable;
+import java.util.Objects;
/**
* Defines the interface to handle exceptions thrown during the execution of a
@@ -28,6 +29,8 @@ public interface ErrorHandlingRunnable extends Runnable, Serializable {
/**
* Handles exceptions thrown during the execution of a FutureAccess.
+ * Exceptions thrown by this method are handled by the default error
+ * handler.
*
* @since 7.1.8
* @param exception
@@ -35,4 +38,38 @@ public interface ErrorHandlingRunnable extends Runnable, Serializable {
*/
public void handleError(Exception exception);
+ /**
+ * Process the given exception in the context of the given runnable. If the
+ * runnable extends {@link ErrorHandlingRunnable}, then the exception is
+ * passed to {@link #handleError(Exception)} and null is returned. If
+ * {@link #handleError(Exception)} throws an exception, that exception is
+ * returned. If the runnable does not extend {@link ErrorHandlingRunnable},
+ * then the original exception is returned.
+ *
+ * @since
+ * @param runnable
+ * the runnable for which the exception should be processed, not
+ * <code>null</code>
+ * @param exception
+ * the exception to process, not <code>null</code>
+ * @return the resulting exception, or <code>null</code> if the exception is
+ * fully processed
+ */
+ public static Exception processException(Runnable runnable,
+ Exception exception) {
+ Objects.requireNonNull(runnable, "The runnable cannot be null.");
+ if (runnable instanceof ErrorHandlingRunnable) {
+ ErrorHandlingRunnable errorHandlingRunnable = (ErrorHandlingRunnable) runnable;
+
+ try {
+ errorHandlingRunnable.handleError(exception);
+ return null;
+ } catch (Exception exceptionFromHandler) {
+ return exceptionFromHandler;
+ }
+ }
+
+ return exception;
+ }
+
}
diff --git a/server/src/main/java/com/vaadin/server/VaadinService.java b/server/src/main/java/com/vaadin/server/VaadinService.java
index a968a89ac6..1e67db708b 100644
--- a/server/src/main/java/com/vaadin/server/VaadinService.java
+++ b/server/src/main/java/com/vaadin/server/VaadinService.java
@@ -40,6 +40,7 @@ import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
@@ -2047,8 +2048,13 @@ public abstract class VaadinService implements Serializable {
try {
pendingAccess.get();
-
} catch (Exception exception) {
+ if (exception instanceof ExecutionException) {
+ Throwable cause = exception.getCause();
+ if (cause instanceof Exception) {
+ exception = (Exception) cause;
+ }
+ }
pendingAccess.handleError(exception);
}
}
diff --git a/server/src/main/java/com/vaadin/server/VaadinSession.java b/server/src/main/java/com/vaadin/server/VaadinSession.java
index 8d246b5696..dd64de4fa5 100644
--- a/server/src/main/java/com/vaadin/server/VaadinSession.java
+++ b/server/src/main/java/com/vaadin/server/VaadinSession.java
@@ -123,11 +123,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
*/
public void handleError(Exception exception) {
try {
- if (runnable instanceof ErrorHandlingRunnable) {
- ErrorHandlingRunnable errorHandlingRunnable = (ErrorHandlingRunnable) runnable;
+ exception = ErrorHandlingRunnable.processException(runnable,
+ exception);
- errorHandlingRunnable.handleError(exception);
- } else {
+ if (exception != null) {
ErrorEvent errorEvent = new ErrorEvent(exception);
ErrorHandler errorHandler = ErrorEvent
diff --git a/server/src/main/java/com/vaadin/ui/UI.java b/server/src/main/java/com/vaadin/ui/UI.java
index 30c01d8cb8..181382603d 100644
--- a/server/src/main/java/com/vaadin/ui/UI.java
+++ b/server/src/main/java/com/vaadin/ui/UI.java
@@ -230,8 +230,8 @@ public abstract class UI extends AbstractSingleComponentContainer
}
json.append("]}");
getRpcProxy(DebugWindowClientRpc.class)
- .reportLayoutProblems(json.toString());
- }
+ .reportLayoutProblems(json.toString());
+}
@Override
public void showServerDesign(Connector connector) {
@@ -1567,17 +1567,45 @@ public abstract class UI extends AbstractSingleComponentContainer
@Override
public void handleError(Exception exception) {
try {
- if (runnable instanceof ErrorHandlingRunnable) {
- ErrorHandlingRunnable errorHandlingRunnable = (ErrorHandlingRunnable) runnable;
-
- errorHandlingRunnable.handleError(exception);
- } else {
+ exception = ErrorHandlingRunnable.processException(runnable,
+ exception);
+
+ if (exception instanceof UIDetachedException) {
+ assert session != null;
+ /*
+ * UI was detached after access was run, but before
+ * accessSynchronously. Furthermore, there wasn't an
+ * ErrorHandlingRunnable that handled the exception.
+ */
+ getLogger().log(Level.WARNING,
+ "access() task ignored because UI got detached after the task was enqueued."
+ + " To suppress this message, change the task to implement {} and make it handle {}."
+ + " Affected task: {}",
+ new Object[] {
+ ErrorHandlingRunnable.class.getName(),
+ UIDetachedException.class.getName(),
+ runnable });
+ } else if (exception != null) {
+ /*
+ * If no ErrorHandlingRunnable, or if it threw an
+ * exception of its own.
+ */
ConnectorErrorEvent errorEvent = new ConnectorErrorEvent(
UI.this, exception);
ErrorHandler errorHandler = com.vaadin.server.ErrorEvent
.findErrorHandler(UI.this);
+ if (errorHandler == null && getSession() == null) {
+ /*
+ * Special case where findErrorHandler(UI) cannot
+ * find the session handler because the UI has
+ * recently been detached.
+ */
+ errorHandler = com.vaadin.server.ErrorEvent
+ .findErrorHandler(session);
+ }
+
if (errorHandler == null) {
errorHandler = new DefaultErrorHandler();
}
@@ -1699,7 +1727,7 @@ public abstract class UI extends AbstractSingleComponentContainer
// If pushMode is disabled then there should never be a pushConnection;
// if enabled there should always be
assert (pushConnection == null)
- ^ getPushConfiguration().getPushMode().isEnabled();
+ ^ getPushConfiguration().getPushMode().isEnabled();
if (pushConnection == this.pushConnection) {
return;