summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/src/com/vaadin/server/AbstractClientConnector.java21
-rw-r--r--server/src/com/vaadin/server/AbstractCommunicationManager.java105
-rw-r--r--server/src/com/vaadin/server/ChangeVariablesErrorEvent.java51
-rw-r--r--server/src/com/vaadin/server/ClientConnector.java47
-rw-r--r--server/src/com/vaadin/server/DefaultErrorHandler.java102
-rw-r--r--server/src/com/vaadin/server/DefaultErrorListener.java62
-rw-r--r--server/src/com/vaadin/server/DragAndDropService.java12
-rw-r--r--server/src/com/vaadin/server/ErrorEvent.java100
-rw-r--r--server/src/com/vaadin/server/ErrorHandler.java (renamed from server/src/com/vaadin/server/ErrorListener.java)8
-rw-r--r--server/src/com/vaadin/server/FileResource.java14
-rw-r--r--server/src/com/vaadin/server/LegacyApplication.java6
-rw-r--r--server/src/com/vaadin/server/StreamVariable.java2
-rw-r--r--server/src/com/vaadin/server/VaadinPortlet.java32
-rw-r--r--server/src/com/vaadin/server/VaadinServlet.java31
-rw-r--r--server/src/com/vaadin/server/VaadinSession.java27
-rw-r--r--server/src/com/vaadin/server/VariableOwner.java13
-rw-r--r--server/src/com/vaadin/ui/AbstractComponent.java61
-rw-r--r--server/src/com/vaadin/ui/Component.java14
-rw-r--r--uitest/src/com/vaadin/tests/appengine/GAESyncTest.java4
-rw-r--r--uitest/src/com/vaadin/tests/application/TerminalErrorNotification.java2
-rw-r--r--uitest/src/com/vaadin/tests/components/AbstractComponentTest.java2
-rw-r--r--uitest/src/com/vaadin/tests/components/abstractfield/TextFieldConversions.java9
-rw-r--r--uitest/src/com/vaadin/tests/components/button/ShortCutListenerModification.java4
-rw-r--r--uitest/src/com/vaadin/tests/errorhandler/ErrorHandlers.java134
24 files changed, 478 insertions, 385 deletions
diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java
index ecdab22160..45c6da7e77 100644
--- a/server/src/com/vaadin/server/AbstractClientConnector.java
+++ b/server/src/com/vaadin/server/AbstractClientConnector.java
@@ -90,6 +90,8 @@ public abstract class AbstractClientConnector implements ClientConnector,
*/
private EventRouter eventRouter = null;
+ private ErrorHandler errorHandler = null;
+
/**
* @deprecated As of 7.0.0, use {@link #markAsDirty()} instead
*/
@@ -951,4 +953,23 @@ public abstract class AbstractClientConnector implements ClientConnector,
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.server.ClientConnector#getErrorHandler()
+ */
+ public ErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.server.ClientConnector#setErrorHandler(com.vaadin.server.
+ * ErrorHandler)
+ */
+ public void setErrorHandler(ErrorHandler errorHandler) {
+ this.errorHandler = errorHandler;
+ }
+
}
diff --git a/server/src/com/vaadin/server/AbstractCommunicationManager.java b/server/src/com/vaadin/server/AbstractCommunicationManager.java
index d1180c479b..86a4f67b4c 100644
--- a/server/src/com/vaadin/server/AbstractCommunicationManager.java
+++ b/server/src/com/vaadin/server/AbstractCommunicationManager.java
@@ -63,6 +63,7 @@ import org.json.JSONObject;
import com.vaadin.annotations.JavaScript;
import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.annotations.StyleSheet;
+import com.vaadin.server.ClientConnector.ConnectorErrorEvent;
import com.vaadin.server.ComponentSizeValidator.InvalidLayout;
import com.vaadin.server.RpcManager.RpcInvocationException;
import com.vaadin.server.StreamVariable.StreamingEndEvent;
@@ -77,7 +78,6 @@ import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.communication.SharedState;
import com.vaadin.shared.communication.UidlValue;
import com.vaadin.shared.ui.ui.UIConstants;
-import com.vaadin.ui.AbstractField;
import com.vaadin.ui.Component;
import com.vaadin.ui.ConnectorTracker;
import com.vaadin.ui.HasComponents;
@@ -299,8 +299,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
} catch (Exception e) {
session.lock();
try {
- handleChangeVariablesError(session, (Component) owner, e,
- new HashMap<String, Object>());
+ handleConnectorRelatedException(owner, e);
} finally {
session.unlock();
}
@@ -347,8 +346,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
} catch (Exception e) {
session.lock();
try {
- handleChangeVariablesError(session, (Component) owner, e,
- new HashMap<String, Object>());
+ handleConnectorRelatedException(owner, e);
} finally {
session.unlock();
}
@@ -1702,13 +1700,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
ServerRpcManager.applyInvocation(connector,
(ServerRpcMethodInvocation) invocation);
} catch (RpcInvocationException e) {
- Throwable realException = e.getCause();
- Component errorComponent = null;
- if (connector instanceof Component) {
- errorComponent = (Component) connector;
- }
- handleChangeVariablesError(uI.getSession(),
- errorComponent, realException, null);
+ handleConnectorRelatedException(connector, e);
}
} else {
@@ -1730,17 +1722,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
+ changes.keySet());
}
} catch (Exception e) {
- Component errorComponent = null;
- if (connector instanceof Component) {
- errorComponent = (Component) connector;
- } else if (connector instanceof DragAndDropService) {
- Object dropHandlerOwner = changes.get("dhowner");
- if (dropHandlerOwner instanceof Component) {
- errorComponent = (Component) dropHandlerOwner;
- }
- }
- handleChangeVariablesError(uI.getSession(),
- errorComponent, e, changes);
+ handleConnectorRelatedException(connector, e);
}
}
}
@@ -1756,6 +1738,24 @@ public abstract class AbstractCommunicationManager implements Serializable {
}
/**
+ * Handles an exception that occurred when processing Rpc calls or a file
+ * upload.
+ *
+ * @param ui
+ * The UI where the exception occured
+ * @param throwable
+ * The exception
+ * @param connector
+ * The Rpc target
+ */
+ private void handleConnectorRelatedException(ClientConnector connector,
+ Throwable throwable) {
+ ErrorEvent errorEvent = new ConnectorErrorEvent(connector, throwable);
+ ErrorHandler handler = ErrorEvent.findErrorHandler(connector);
+ handler.error(errorEvent);
+ }
+
+ /**
* Parse a message burst from the client into a list of MethodInvocation
* instances.
*
@@ -1952,65 +1952,6 @@ public abstract class AbstractCommunicationManager implements Serializable {
return result;
}
- public class ErrorHandlerErrorEvent implements ErrorEvent, Serializable {
- private final Throwable throwable;
-
- public ErrorHandlerErrorEvent(Throwable throwable) {
- this.throwable = throwable;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- }
-
- /**
- * Handles an error (exception) that occurred when processing variable
- * changes from the client or a failure of a file upload.
- *
- * For {@link AbstractField} components,
- * {@link AbstractField#handleError(com.vaadin.ui.AbstractComponent.ComponentErrorEvent)}
- * is called. In all other cases (or if the field does not handle the
- * error), {@link ErrorListener#terminalError(ErrorEvent)} for the session
- * error handler is called.
- *
- * @param session
- * @param owner
- * component that the error concerns
- * @param e
- * exception that occurred
- * @param m
- * map from variable names to values
- */
- private void handleChangeVariablesError(VaadinSession session,
- Component owner, Throwable t, Map<String, Object> m) {
- boolean handled = false;
- ChangeVariablesErrorEvent errorEvent = new ChangeVariablesErrorEvent(
- owner, t, m);
-
- if (owner instanceof AbstractField) {
- try {
- handled = ((AbstractField<?>) owner).handleError(errorEvent);
- } catch (Exception handlerException) {
- /*
- * If there is an error in the component error handler we pass
- * the that error to the session error handler and continue
- * processing the actual error
- */
- session.getErrorHandler().terminalError(
- new ErrorHandlerErrorEvent(handlerException));
- handled = false;
- }
- }
-
- if (!handled) {
- session.getErrorHandler().terminalError(errorEvent);
- }
-
- }
-
/**
* Unescape encoded burst separator characters in a burst received from the
* client. This protects from separator injection attacks.
diff --git a/server/src/com/vaadin/server/ChangeVariablesErrorEvent.java b/server/src/com/vaadin/server/ChangeVariablesErrorEvent.java
deleted file mode 100644
index f208fffcef..0000000000
--- a/server/src/com/vaadin/server/ChangeVariablesErrorEvent.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2011 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.vaadin.server;
-
-import java.util.Map;
-
-import com.vaadin.ui.AbstractComponent.ComponentErrorEvent;
-import com.vaadin.ui.Component;
-
-@SuppressWarnings("serial")
-public class ChangeVariablesErrorEvent implements ComponentErrorEvent {
-
- private Throwable throwable;
- private Component component;
-
- private Map<String, Object> variableChanges;
-
- public ChangeVariablesErrorEvent(Component component, Throwable throwable,
- Map<String, Object> variableChanges) {
- this.component = component;
- this.throwable = throwable;
- this.variableChanges = variableChanges;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- public Component getComponent() {
- return component;
- }
-
- public Map<String, Object> getVariableChanges() {
- return variableChanges;
- }
-
-} \ No newline at end of file
diff --git a/server/src/com/vaadin/server/ClientConnector.java b/server/src/com/vaadin/server/ClientConnector.java
index b46ef58fcd..440f282508 100644
--- a/server/src/com/vaadin/server/ClientConnector.java
+++ b/server/src/com/vaadin/server/ClientConnector.java
@@ -38,6 +38,32 @@ import com.vaadin.ui.UI;
*/
public interface ClientConnector extends Connector {
/**
+ * An error event for connector related errors. Use {@link #getConnector()}
+ * to find the connector where the error occurred or {@link #getComponent()}
+ * to find the nearest parent component.
+ */
+ public static class ConnectorErrorEvent extends
+ com.vaadin.server.ErrorEvent {
+
+ private Connector connector;
+
+ public ConnectorErrorEvent(Connector connector, Throwable t) {
+ super(t);
+ this.connector = connector;
+ }
+
+ /**
+ * Gets the connector for which this error occurred.
+ *
+ * @return The connector for which the error occurred
+ */
+ public Connector getConnector() {
+ return connector;
+ }
+
+ }
+
+ /**
* Returns the list of pending server to client RPC calls and clears the
* list.
*
@@ -249,4 +275,25 @@ public interface ClientConnector extends Connector {
* @return RpcManager or null if none found for the interface
*/
public RpcManager getRpcManager(String rpcInterfaceName);
+
+ /**
+ * Gets the error handler for the connector.
+ *
+ * The error handler is dispatched whenever there is an error processing the
+ * data coming from the client to this connector.
+ *
+ * @return The error handler or null if not set
+ */
+ public ErrorHandler getErrorHandler();
+
+ /**
+ * Sets the error handler for the connector.
+ *
+ * The error handler is dispatched whenever there is an error processing the
+ * data coming from the client for this connector.
+ *
+ * @param errorHandler
+ * The error handler for this connector
+ */
+ public void setErrorHandler(ErrorHandler errorHandler);
}
diff --git a/server/src/com/vaadin/server/DefaultErrorHandler.java b/server/src/com/vaadin/server/DefaultErrorHandler.java
new file mode 100644
index 0000000000..de77b48a25
--- /dev/null
+++ b/server/src/com/vaadin/server/DefaultErrorHandler.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2011 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.server;
+
+import java.net.SocketException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.vaadin.server.ClientConnector.ConnectorErrorEvent;
+import com.vaadin.shared.Connector;
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.Component;
+
+public class DefaultErrorHandler implements ErrorHandler {
+ @Override
+ public void error(ErrorEvent event) {
+ doDefault(event);
+ }
+
+ public static void doDefault(ErrorEvent event) {
+ final Throwable t = event.getThrowable();
+ if (t instanceof SocketException) {
+ // Most likely client browser closed socket
+ getLogger().info(
+ "SocketException in CommunicationManager."
+ + " Most likely client (browser) closed socket.");
+ return;
+ }
+
+ // Finds the original source of the error/exception
+ AbstractComponent component = findAbstractComponent(event);
+ if (component != null) {
+ // Shows the error in AbstractComponent
+ ErrorMessage errorMessage = AbstractErrorMessage
+ .getErrorMessageForException(t);
+ component.setComponentError(errorMessage);
+ }
+
+ // also print the error on console
+ getLogger().log(Level.SEVERE, "", t);
+ }
+
+ private static Logger getLogger() {
+ return Logger.getLogger(DefaultErrorHandler.class.getName());
+ }
+
+ /**
+ * Returns the AbstractComponent associated with the given error if such can
+ * be found
+ *
+ * @param event
+ * The error to investigate
+ * @return The {@link AbstractComponent} to error relates to or null if
+ * could not be determined or if the error does not relate to any
+ * AbstractComponent.
+ */
+ public static AbstractComponent findAbstractComponent(
+ com.vaadin.server.ErrorEvent event) {
+ if (event instanceof ConnectorErrorEvent) {
+ Component c = findComponent(((ConnectorErrorEvent) event)
+ .getConnector());
+ if (c instanceof AbstractComponent) {
+ return (AbstractComponent) c;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Finds the nearest component by traversing upwards in the hierarchy. If
+ * connector is a Component, that Component is returned. Otherwise, looks
+ * upwards in the hierarchy until it finds a {@link Component}.
+ *
+ * @return A Component or null if no component was found
+ */
+ public static Component findComponent(Connector connector) {
+ if (connector instanceof Component) {
+ return (Component) connector;
+ }
+ if (connector.getParent() != null) {
+ return findComponent(connector.getParent());
+ }
+
+ return null;
+ }
+
+} \ No newline at end of file
diff --git a/server/src/com/vaadin/server/DefaultErrorListener.java b/server/src/com/vaadin/server/DefaultErrorListener.java
deleted file mode 100644
index 71fccf8d0c..0000000000
--- a/server/src/com/vaadin/server/DefaultErrorListener.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2011 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.vaadin.server;
-
-import java.net.SocketException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.ui.AbstractComponent;
-
-public class DefaultErrorListener implements ErrorListener {
- @Override
- public void terminalError(ErrorEvent event) {
- doDefault(event);
- }
-
- public static void doDefault(ErrorEvent event) {
- final Throwable t = event.getThrowable();
- if (t instanceof SocketException) {
- // Most likely client browser closed socket
- getLogger().info(
- "SocketException in CommunicationManager."
- + " Most likely client (browser) closed socket.");
- return;
- }
-
- // Finds the original source of the error/exception
- Object owner = null;
- if (event instanceof VariableOwner.ErrorEvent) {
- owner = ((VariableOwner.ErrorEvent) event).getVariableOwner();
- } else if (event instanceof ChangeVariablesErrorEvent) {
- owner = ((ChangeVariablesErrorEvent) event).getComponent();
- }
-
- // Shows the error in AbstractComponent
- if (owner instanceof AbstractComponent) {
- ((AbstractComponent) owner).setComponentError(AbstractErrorMessage
- .getErrorMessageForException(t));
- }
-
- // also print the error on console
- getLogger().log(Level.SEVERE, "Terminal error:", t);
- }
-
- private static Logger getLogger() {
- return Logger.getLogger(DefaultErrorListener.class.getName());
- }
-} \ No newline at end of file
diff --git a/server/src/com/vaadin/server/DragAndDropService.java b/server/src/com/vaadin/server/DragAndDropService.java
index a864f8fb16..0fa39fa0e8 100644
--- a/server/src/com/vaadin/server/DragAndDropService.java
+++ b/server/src/com/vaadin/server/DragAndDropService.java
@@ -53,6 +53,8 @@ public class DragAndDropService implements VariableOwner, ClientConnector {
private AcceptCriterion acceptCriterion;
+ private ErrorHandler errorHandler;
+
public DragAndDropService(AbstractCommunicationManager manager) {
this.manager = manager;
}
@@ -346,4 +348,14 @@ public class DragAndDropService implements VariableOwner, ClientConnector {
VaadinResponse response, String path) throws IOException {
return false;
}
+
+ @Override
+ public ErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
+ @Override
+ public void setErrorHandler(ErrorHandler errorHandler) {
+ this.errorHandler = errorHandler;
+ }
}
diff --git a/server/src/com/vaadin/server/ErrorEvent.java b/server/src/com/vaadin/server/ErrorEvent.java
index b570271cf7..27754bfae6 100644
--- a/server/src/com/vaadin/server/ErrorEvent.java
+++ b/server/src/com/vaadin/server/ErrorEvent.java
@@ -17,14 +17,108 @@ package com.vaadin.server;
import java.io.Serializable;
+import com.vaadin.shared.Connector;
+import com.vaadin.ui.UI;
+
/**
- * An error event implementation for Terminal.
+ * An error thrown by the framework and handled by an {@link ErrorHandler}.
+ * Typically handled by {@link VaadinSession#getErrorHandler()} but can also be
+ * handled by a {@link Connector} specific handler, set using
+ * {@link ClientConnector#setErrorHandler(ErrorHandler)}.
+ *
*/
-public interface ErrorEvent extends Serializable {
+public class ErrorEvent implements Serializable {
+
+ private Throwable throwable;
+
+ public ErrorEvent(Throwable t) {
+ setThrowable(t);
+ }
/**
* Gets the contained throwable, the cause of the error.
+ *
+ * @return
+ */
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ public void setThrowable(Throwable throwable) {
+ this.throwable = throwable;
+ }
+
+ /**
+ * Method for finding the error handler for the given connector. Uses
+ * connector hierarchy to find a connector with an error handler. Falls back
+ * to the VaadinSession error handler if no connector has specified an error
+ * handler.
+ * <p>
+ * Returns a {@link DefaultErrorHandler} if no error handler was found
+ * </p>
+ *
+ * @param connector
+ * The target connector
+ * @return An ErrorHandler for the connector
+ */
+ public static ErrorHandler findErrorHandler(ClientConnector connector) {
+ if (connector != null) {
+ ErrorHandler errorHandler = connector.getErrorHandler();
+ if (errorHandler != null) {
+ return errorHandler;
+ }
+
+ ClientConnector parent = connector.getParent();
+ if (parent != null) {
+ return findErrorHandler(parent);
+ }
+
+ /*
+ * Reached UI and found no error handler. Try session which
+ * typically has one.
+ */
+ UI ui = connector.getUI();
+ if (ui != null) {
+ errorHandler = findErrorHandler(ui.getSession());
+ if (errorHandler != null) {
+ return errorHandler;
+ }
+ }
+ }
+
+ /*
+ * No connector known or the connector is not attached to a session. Try
+ * the current session
+ */
+ if (VaadinSession.getCurrent() != null) {
+ ErrorHandler errorHandler = VaadinSession.getCurrent()
+ .getErrorHandler();
+ if (errorHandler != null) {
+ return errorHandler;
+ }
+ }
+
+ /*
+ * We should never really get here as at least the session should have
+ * an error handler. If for some reason it does not we use the default
+ * error handler.
+ */
+ return new DefaultErrorHandler();
+ }
+
+ /**
+ * Method for finding the error handler for the given session.
+ *
+ * @param connector
+ * The target connector
+ *
+ * @return An ErrorHandler for the session or null if none was found
*/
- public Throwable getThrowable();
+ public static ErrorHandler findErrorHandler(VaadinSession session) {
+ if (session == null) {
+ return null;
+ }
+ return session.getErrorHandler();
+ }
} \ No newline at end of file
diff --git a/server/src/com/vaadin/server/ErrorListener.java b/server/src/com/vaadin/server/ErrorHandler.java
index 07400852e0..36500a7f53 100644
--- a/server/src/com/vaadin/server/ErrorListener.java
+++ b/server/src/com/vaadin/server/ErrorHandler.java
@@ -18,15 +18,15 @@ package com.vaadin.server;
import java.io.Serializable;
/**
- * Interface for listening to Terminal errors.
+ * Interface for listening to errors in the application.
*/
-public interface ErrorListener extends Serializable {
+public interface ErrorHandler extends Serializable {
/**
- * Invoked when a terminal error occurs.
+ * Invoked when an error occurs.
*
* @param event
* the fired event.
*/
- public void terminalError(ErrorEvent event);
+ public void error(ErrorEvent event);
} \ No newline at end of file
diff --git a/server/src/com/vaadin/server/FileResource.java b/server/src/com/vaadin/server/FileResource.java
index c413bb471d..42f214c64a 100644
--- a/server/src/com/vaadin/server/FileResource.java
+++ b/server/src/com/vaadin/server/FileResource.java
@@ -71,18 +71,8 @@ public class FileResource implements ConnectorResource {
ds.setCacheTime(cacheTime);
return ds;
} catch (final FileNotFoundException e) {
- // Log the exception using the application error handler
- VaadinSession.getCurrent().getErrorHandler()
- .terminalError(new ErrorEvent() {
-
- @Override
- public Throwable getThrowable() {
- return e;
- }
-
- });
-
- return null;
+ throw new RuntimeException("File not found: "
+ + sourceFile.getName(), e);
}
}
diff --git a/server/src/com/vaadin/server/LegacyApplication.java b/server/src/com/vaadin/server/LegacyApplication.java
index dc55bca344..598cfbf832 100644
--- a/server/src/com/vaadin/server/LegacyApplication.java
+++ b/server/src/com/vaadin/server/LegacyApplication.java
@@ -38,7 +38,7 @@ import com.vaadin.ui.UI;
* @since 7.0
*/
@Deprecated
-public abstract class LegacyApplication implements ErrorListener {
+public abstract class LegacyApplication implements ErrorHandler {
private LegacyWindow mainWindow;
private String theme;
@@ -208,8 +208,8 @@ public abstract class LegacyApplication implements ErrorListener {
}
@Override
- public void terminalError(ErrorEvent event) {
- DefaultErrorListener.doDefault(event);
+ public void error(ErrorEvent event) {
+ DefaultErrorHandler.doDefault(event);
}
public VaadinSession getContext() {
diff --git a/server/src/com/vaadin/server/StreamVariable.java b/server/src/com/vaadin/server/StreamVariable.java
index a75cc2f0d7..8a664f22c0 100644
--- a/server/src/com/vaadin/server/StreamVariable.java
+++ b/server/src/com/vaadin/server/StreamVariable.java
@@ -151,7 +151,7 @@ public interface StreamVariable extends Serializable {
* the streaming ended before the end of the input. The streaming may fail
* due an interruption by {@link } or due an other unknown exception in
* communication. In the latter case the exception is also passed to
- * {@link VaadinSession#terminalError(com.vaadin.server.Terminal.ErrorEvent)}
+ * {@link VaadinSession#error(com.vaadin.server.Terminal.ErrorEvent)}
* .
*/
public interface StreamingErrorEvent extends StreamingEvent {
diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java
index d7d4a65245..05b6ac360a 100644
--- a/server/src/com/vaadin/server/VaadinPortlet.java
+++ b/server/src/com/vaadin/server/VaadinPortlet.java
@@ -21,7 +21,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
-import java.io.Serializable;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.security.GeneralSecurityException;
@@ -653,6 +652,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants {
// portlet
// if this was an UIDL request, response UIDL back to client
+ ErrorHandler errorHandler = ErrorEvent.findErrorHandler(vaadinSession);
if (getRequestType(request) == RequestType.UIDL) {
SystemMessages ci = getService().getSystemMessages(
ServletPortletHelper.findLocale(null, vaadinSession,
@@ -660,33 +660,17 @@ public class VaadinPortlet extends GenericPortlet implements Constants {
criticalNotification(request, response,
ci.getInternalErrorCaption(), ci.getInternalErrorMessage(),
null, ci.getInternalErrorURL());
- if (vaadinSession != null) {
- vaadinSession.getErrorHandler().terminalError(
- new RequestError(e));
+ if (errorHandler != null) {
+ errorHandler.error(new ErrorEvent(e));
+ }
+ } else {
+ if (errorHandler != null) {
+ errorHandler.error(new ErrorEvent(e));
} else {
+ // Re-throw other exceptions
throw new PortletException(e);
}
- } else {
- // Re-throw other exceptions
- throw new PortletException(e);
}
-
- }
-
- @SuppressWarnings("serial")
- public class RequestError implements ErrorEvent, Serializable {
-
- private final Throwable throwable;
-
- public RequestError(Throwable throwable) {
- this.throwable = throwable;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
}
/**
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index e48153642b..3089eccc12 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/com/vaadin/server/VaadinServlet.java
@@ -21,7 +21,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
-import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
@@ -573,6 +572,8 @@ public class VaadinServlet extends HttpServlet implements Constants {
private void handleServiceException(VaadinServletRequest request,
VaadinServletResponse response, VaadinSession vaadinSession,
Throwable e) throws IOException, ServletException {
+ ErrorHandler errorHandler = ErrorEvent.findErrorHandler(vaadinSession);
+
// if this was an UIDL request, response UIDL back to client
if (getRequestType(request) == RequestType.UIDL) {
SystemMessages ci = getService().getSystemMessages(
@@ -581,15 +582,16 @@ public class VaadinServlet extends HttpServlet implements Constants {
criticalNotification(request, response,
ci.getInternalErrorCaption(), ci.getInternalErrorMessage(),
null, ci.getInternalErrorURL());
- if (vaadinSession != null) {
- vaadinSession.getErrorHandler().terminalError(
- new RequestError(e));
+ if (errorHandler != null) {
+ errorHandler.error(new ErrorEvent(e));
+ }
+ } else {
+ if (errorHandler != null) {
+ errorHandler.error(new ErrorEvent(e));
} else {
+ // Re-throw other exceptions
throw new ServletException(e);
}
- } else {
- // Re-throw other exceptions
- throw new ServletException(e);
}
}
@@ -1217,21 +1219,6 @@ public class VaadinServlet extends HttpServlet implements Constants {
return u;
}
- public class RequestError implements ErrorEvent, Serializable {
-
- private final Throwable throwable;
-
- public RequestError(Throwable throwable) {
- this.throwable = throwable;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- }
-
/**
* Escapes characters to html entities. An exception is made for some
* "safe characters" to keep the text somewhat readable.
diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java
index 9bfd03b402..87f5be3e2c 100644
--- a/server/src/com/vaadin/server/VaadinSession.java
+++ b/server/src/com/vaadin/server/VaadinSession.java
@@ -90,7 +90,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* Session wide error handler which is used by default if an error is left
* unhandled.
*/
- private ErrorListener errorHandler = new DefaultErrorListener();
+ private ErrorHandler errorHandler = new DefaultErrorHandler();
/**
* The converter factory that is used to provide default converters for the
@@ -338,7 +338,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
*
* @return the current error handler
*/
- public ErrorListener getErrorHandler() {
+ public ErrorHandler getErrorHandler() {
return errorHandler;
}
@@ -347,7 +347,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
*
* @param errorHandler
*/
- public void setErrorHandler(ErrorListener errorHandler) {
+ public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
@@ -389,27 +389,6 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
}
/**
- * Application error is an error message defined on the application level.
- *
- * When an error occurs on the application level, this error message4 type
- * should be used. This indicates that the problem is caused by the
- * application - not by the user.
- */
- public class ApplicationError implements ErrorEvent {
- private final Throwable throwable;
-
- public ApplicationError(Throwable throwable) {
- this.throwable = throwable;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- }
-
- /**
* Adds a request handler to this session. Request handlers can be added to
* provide responses to requests that are not handled by the default
* functionality of the framework.
diff --git a/server/src/com/vaadin/server/VariableOwner.java b/server/src/com/vaadin/server/VariableOwner.java
index e4319cfaf3..825a5804ef 100644
--- a/server/src/com/vaadin/server/VariableOwner.java
+++ b/server/src/com/vaadin/server/VariableOwner.java
@@ -81,17 +81,4 @@ public interface VariableOwner extends Serializable {
*/
public boolean isImmediate();
- /**
- * VariableOwner error event.
- */
- public interface ErrorEvent extends com.vaadin.server.ErrorEvent {
-
- /**
- * Gets the source VariableOwner.
- *
- * @return the variable owner.
- */
- public VariableOwner getVariableOwner();
-
- }
}
diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java
index 2ce3e25b2a..811a1dc2f6 100644
--- a/server/src/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/com/vaadin/ui/AbstractComponent.java
@@ -30,6 +30,7 @@ import com.vaadin.event.ShortcutListener;
import com.vaadin.server.AbstractClientConnector;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.ComponentSizeValidator;
+import com.vaadin.server.ErrorHandler;
import com.vaadin.server.ErrorMessage;
import com.vaadin.server.Resource;
import com.vaadin.server.VaadinSession;
@@ -83,7 +84,7 @@ public abstract class AbstractComponent extends AbstractClientConnector
private static final Pattern sizePattern = Pattern
.compile("^(-?\\d+(\\.\\d+)?)(%|px|em|ex|in|cm|mm|pt|pc)?$");
- private ComponentErrorHandler errorHandler = null;
+ private ErrorHandler errorHandler = null;
/**
* Keeps track of the Actions added to this component; the actual
@@ -891,64 +892,6 @@ public abstract class AbstractComponent extends AbstractClientConnector
}
}
- public interface ComponentErrorEvent extends com.vaadin.server.ErrorEvent {
- }
-
- public interface ComponentErrorHandler extends Serializable {
- /**
- * Handle the component error
- *
- * @param event
- * @return True if the error has been handled False, otherwise
- */
- public boolean handleComponentError(ComponentErrorEvent event);
- }
-
- /**
- * Gets the error handler for the component.
- *
- * The error handler is dispatched whenever there is an error processing the
- * data coming from the client.
- *
- * @return
- */
- public ComponentErrorHandler getErrorHandler() {
- return errorHandler;
- }
-
- /**
- * Sets the error handler for the component.
- *
- * The error handler is dispatched whenever there is an error processing the
- * data coming from the client.
- *
- * If the error handler is not set, the application error handler is used to
- * handle the exception.
- *
- * @param errorHandler
- * AbstractField specific error handler
- */
- public void setErrorHandler(ComponentErrorHandler errorHandler) {
- this.errorHandler = errorHandler;
- }
-
- /**
- * Handle the component error event.
- *
- * @param error
- * Error event to handle
- * @return True if the error has been handled False, otherwise. If the error
- * haven't been handled by this component, it will be handled in the
- * application error handler.
- */
- public boolean handleError(ComponentErrorEvent error) {
- if (errorHandler != null) {
- return errorHandler.handleComponentError(error);
- }
- return false;
-
- }
-
/*
* Actions
*/
diff --git a/server/src/com/vaadin/ui/Component.java b/server/src/com/vaadin/ui/Component.java
index 4797bb702c..85140a8351 100644
--- a/server/src/com/vaadin/ui/Component.java
+++ b/server/src/com/vaadin/ui/Component.java
@@ -954,20 +954,6 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
}
/**
- * Listener interface for receiving <code>Component.Errors</code>s.
- */
- public interface ErrorListener extends EventListener, Serializable {
-
- /**
- * Notifies the listener of a component error.
- *
- * @param event
- * the event that has occured.
- */
- public void componentError(Component.ErrorEvent event);
- }
-
- /**
* A sub-interface implemented by components that can obtain input focus.
* This includes all {@link Field} components as well as some other
* components, such as {@link Upload}.
diff --git a/uitest/src/com/vaadin/tests/appengine/GAESyncTest.java b/uitest/src/com/vaadin/tests/appengine/GAESyncTest.java
index f5d90bae79..146e85f5f3 100644
--- a/uitest/src/com/vaadin/tests/appengine/GAESyncTest.java
+++ b/uitest/src/com/vaadin/tests/appengine/GAESyncTest.java
@@ -29,7 +29,7 @@ public class GAESyncTest extends LegacyApplication {
}
@Override
- public void terminalError(com.vaadin.server.ErrorEvent event) {
+ public void error(com.vaadin.server.ErrorEvent event) {
Throwable t = event.getThrowable();
// Was this caused by a GAE timeout?
while (t != null) {
@@ -41,7 +41,7 @@ public class GAESyncTest extends LegacyApplication {
t = t.getCause();
}
- super.terminalError(event);
+ super.error(event);
}
diff --git a/uitest/src/com/vaadin/tests/application/TerminalErrorNotification.java b/uitest/src/com/vaadin/tests/application/TerminalErrorNotification.java
index 9dee2fe0b6..2c8d7e01af 100644
--- a/uitest/src/com/vaadin/tests/application/TerminalErrorNotification.java
+++ b/uitest/src/com/vaadin/tests/application/TerminalErrorNotification.java
@@ -38,7 +38,7 @@ public class TerminalErrorNotification extends TestBase {
}
@Override
- public void terminalError(com.vaadin.server.ErrorEvent event) {
+ public void error(com.vaadin.server.ErrorEvent event) {
event.getThrowable().printStackTrace();
UI mainWindow = getMainWindow();
diff --git a/uitest/src/com/vaadin/tests/components/AbstractComponentTest.java b/uitest/src/com/vaadin/tests/components/AbstractComponentTest.java
index f36437326a..c086e03ae0 100644
--- a/uitest/src/com/vaadin/tests/components/AbstractComponentTest.java
+++ b/uitest/src/com/vaadin/tests/components/AbstractComponentTest.java
@@ -715,7 +715,7 @@ public abstract class AbstractComponentTest<T extends AbstractComponent>
}
@Override
- public void terminalError(com.vaadin.server.ErrorEvent event) {
+ public void error(com.vaadin.server.ErrorEvent event) {
String logMsg = "Exception occured, "
+ event.getThrowable().getClass().getName();
diff --git a/uitest/src/com/vaadin/tests/components/abstractfield/TextFieldConversions.java b/uitest/src/com/vaadin/tests/components/abstractfield/TextFieldConversions.java
index 3a8275bd51..888922b69d 100644
--- a/uitest/src/com/vaadin/tests/components/abstractfield/TextFieldConversions.java
+++ b/uitest/src/com/vaadin/tests/components/abstractfield/TextFieldConversions.java
@@ -5,9 +5,9 @@ import java.util.Date;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.server.ErrorEvent;
+import com.vaadin.server.ErrorHandler;
import com.vaadin.server.UserError;
-import com.vaadin.ui.AbstractComponent.ComponentErrorEvent;
-import com.vaadin.ui.AbstractComponent.ComponentErrorHandler;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.TextField;
@@ -41,12 +41,11 @@ public class TextFieldConversions extends AbstractComponentDataBindingTest {
tf = new TextField("TextField");
addComponent(tf);
- tf.setErrorHandler(new ComponentErrorHandler() {
+ tf.setErrorHandler(new ErrorHandler() {
@Override
- public boolean handleComponentError(ComponentErrorEvent event) {
+ public void error(ErrorEvent event) {
tf.setComponentError(new UserError("Invalid value"));
- return true;
}
});
}
diff --git a/uitest/src/com/vaadin/tests/components/button/ShortCutListenerModification.java b/uitest/src/com/vaadin/tests/components/button/ShortCutListenerModification.java
index 51ca47b4b7..9cdd803fe0 100644
--- a/uitest/src/com/vaadin/tests/components/button/ShortCutListenerModification.java
+++ b/uitest/src/com/vaadin/tests/components/button/ShortCutListenerModification.java
@@ -57,8 +57,8 @@ public class ShortCutListenerModification extends TestBase implements
}
@Override
- public void terminalError(com.vaadin.server.ErrorEvent event) {
- super.terminalError(event);
+ public void error(com.vaadin.server.ErrorEvent event) {
+ super.error(event);
getMainWindow().showNotification("Failed!",
Notification.TYPE_ERROR_MESSAGE);
diff --git a/uitest/src/com/vaadin/tests/errorhandler/ErrorHandlers.java b/uitest/src/com/vaadin/tests/errorhandler/ErrorHandlers.java
new file mode 100644
index 0000000000..c5ff1be1ed
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/errorhandler/ErrorHandlers.java
@@ -0,0 +1,134 @@
+package com.vaadin.tests.errorhandler;
+
+import java.lang.reflect.InvocationTargetException;
+
+import com.vaadin.event.ListenerMethod.MethodException;
+import com.vaadin.server.DefaultErrorHandler;
+import com.vaadin.server.ErrorHandler;
+import com.vaadin.server.RpcManager.RpcInvocationException;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Notification.Type;
+import com.vaadin.ui.VerticalLayout;
+
+public class ErrorHandlers extends AbstractTestUI {
+
+ public static class NotificationErrorHandler implements ErrorHandler {
+
+ @Override
+ public void error(com.vaadin.server.ErrorEvent event) {
+ Notification.show(getErrorMessage(event), Type.ERROR_MESSAGE);
+ }
+
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ addComponent(runtimeExceptionOnClick(new Button("Standard button")));
+ addComponent(npeOnClick(new Button("Standard button with NPE")));
+ Button customErrorButton = notificationErrorHandler(new Button(
+ "Button with notification error handler"));
+ addComponent(runtimeExceptionOnClick(customErrorButton));
+
+ final VerticalLayout layoutWithErrorHandler = new VerticalLayout(
+ runtimeExceptionOnClick(new Button("Error handler on parent")));
+ ErrorHandler e = new ErrorHandler() {
+
+ @Override
+ public void error(com.vaadin.server.ErrorEvent event) {
+ layoutWithErrorHandler.addComponent(new Label("Layout error: "
+ + getErrorMessage(event)));
+ }
+
+ };
+ layoutWithErrorHandler.setErrorHandler(e);
+ layoutWithErrorHandler
+ .addComponent(notificationErrorHandler(npeOnClick(new Button(
+ "Error handler on button and parent"))));
+ addComponent(layoutWithErrorHandler);
+ }
+
+ private Button notificationErrorHandler(Button button) {
+ button.setErrorHandler(new NotificationErrorHandler());
+ return button;
+ }
+
+ protected static String getErrorMessage(com.vaadin.server.ErrorEvent event) {
+ Component c = DefaultErrorHandler.findAbstractComponent(event);
+ String errorMsg = "Error: '" + getMessage(event) + "' in ";
+ errorMsg += c.getClass().getSimpleName() + " with caption '"
+ + c.getCaption() + "'";
+ return errorMsg;
+ }
+
+ private static String getMessage(com.vaadin.server.ErrorEvent event) {
+ Throwable e = getUserCodeException(event);
+ if (e.getMessage() != null) {
+ return e.getMessage();
+ } else {
+ return e.getClass().getSimpleName();
+ }
+ }
+
+ private static Throwable getUserCodeException(
+ com.vaadin.server.ErrorEvent event) {
+ Throwable t = event.getThrowable();
+ if (t instanceof RpcInvocationException) {
+ t = t.getCause();
+ }
+ if (t instanceof InvocationTargetException) {
+ t = t.getCause();
+ }
+ if (t instanceof MethodException) {
+ t = t.getCause();
+ }
+
+ return t;
+
+ }
+
+ private Button runtimeExceptionOnClick(Button customErrorButton) {
+ customErrorButton.setCaption("RE: " + customErrorButton.getCaption());
+
+ customErrorButton.addClickListener(new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ throw new RuntimeException("Fail in click event");
+ }
+ });
+ return customErrorButton;
+ }
+
+ private Button npeOnClick(Button customErrorButton) {
+ customErrorButton.setCaption("NPE: " + customErrorButton.getCaption());
+ customErrorButton.addClickListener(new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ Integer i = null;
+ i += 2;
+ }
+ });
+ return customErrorButton;
+ }
+
+ @Override
+ protected String getTestDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}