* Replaced AbstractComponent ErrorHandler with ClientConnector level error handler. Now uses the same ErrorHandler as other parts of the framework.
* Made error handling hierarchical so that the error handler of the connector where the error occured or its ancestors is used. Falls back to VaadinSession ErrorHandler.
* Changed ErrorEvent to be a class as all other events in the framework
* Renamed ErrorListener to ErrorHandler and DefaultErrorListener to DefaultErrorHandler for consistency
* Unified error handling in AbstractCommunicationManager
* Unified error handling in VaadinServlet and VaadinPortlet
* Removed superfluous ErrorEvent implementations (#10232)
Change-Id: Ied518e05209fe54685f4bebab0709b1cd5584fd1
*/
private EventRouter eventRouter = null;
+ private ErrorHandler errorHandler = null;
+
/**
* @deprecated As of 7.0.0, use {@link #markAsDirty()} instead
*/
}
+ /*
+ * (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;
+ }
+
}
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;
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;
} catch (Exception e) {
session.lock();
try {
- handleChangeVariablesError(session, (Component) owner, e,
- new HashMap<String, Object>());
+ handleConnectorRelatedException(owner, e);
} finally {
session.unlock();
}
} catch (Exception e) {
session.lock();
try {
- handleChangeVariablesError(session, (Component) owner, e,
- new HashMap<String, Object>());
+ handleConnectorRelatedException(owner, e);
} finally {
session.unlock();
}
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 {
+ 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);
}
}
}
return success;
}
+ /**
+ * 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.
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.
+++ /dev/null
-/*
- * 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
*
*/
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.
* @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);
}
--- /dev/null
+/*
+ * 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
+++ /dev/null
-/*
- * 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
private AcceptCriterion acceptCriterion;
+ private ErrorHandler errorHandler;
+
public DragAndDropService(AbstractCommunicationManager manager) {
this.manager = manager;
}
VaadinResponse response, String path) throws IOException {
return false;
}
+
+ @Override
+ public ErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
+ @Override
+ public void setErrorHandler(ErrorHandler errorHandler) {
+ this.errorHandler = errorHandler;
+ }
}
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
--- /dev/null
+/*
+ * 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.io.Serializable;
+
+/**
+ * Interface for listening to errors in the application.
+ */
+public interface ErrorHandler extends Serializable {
+
+ /**
+ * Invoked when an error occurs.
+ *
+ * @param event
+ * the fired event.
+ */
+ public void error(ErrorEvent event);
+}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.io.Serializable;
-
-/**
- * Interface for listening to Terminal errors.
- */
-public interface ErrorListener extends Serializable {
-
- /**
- * Invoked when a terminal error occurs.
- *
- * @param event
- * the fired event.
- */
- public void terminalError(ErrorEvent event);
-}
\ No newline at end of file
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);
}
}
* @since 7.0
*/
@Deprecated
-public abstract class LegacyApplication implements ErrorListener {
+public abstract class LegacyApplication implements ErrorHandler {
private LegacyWindow mainWindow;
private String theme;
}
@Override
- public void terminalError(ErrorEvent event) {
- DefaultErrorListener.doDefault(event);
+ public void error(ErrorEvent event) {
+ DefaultErrorHandler.doDefault(event);
}
public VaadinSession getContext() {
* 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 {
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;
// 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,
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;
- }
-
}
/**
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;
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(
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);
}
}
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.
* 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
*
* @return the current error handler
*/
- public ErrorListener getErrorHandler() {
+ public ErrorHandler getErrorHandler() {
return errorHandler;
}
*
* @param errorHandler
*/
- public void setErrorHandler(ErrorListener errorHandler) {
+ public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
this.converterFactory = converterFactory;
}
- /**
- * 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
*/
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();
-
- }
}
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;
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
}
}
- 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
*/
}
}
- /**
- * 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
}
@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) {
t = t.getCause();
}
- super.terminalError(event);
+ super.error(event);
}
}
@Override
- public void terminalError(com.vaadin.server.ErrorEvent event) {
+ public void error(com.vaadin.server.ErrorEvent event) {
event.getThrowable().printStackTrace();
UI mainWindow = getMainWindow();
}
@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();
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;
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;
}
});
}
}
@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);
--- /dev/null
+package com.vaadin.tests.errorhandler;\r
+\r
+import java.lang.reflect.InvocationTargetException;\r
+\r
+import com.vaadin.event.ListenerMethod.MethodException;\r
+import com.vaadin.server.DefaultErrorHandler;\r
+import com.vaadin.server.ErrorHandler;\r
+import com.vaadin.server.RpcManager.RpcInvocationException;\r
+import com.vaadin.server.VaadinRequest;\r
+import com.vaadin.tests.components.AbstractTestUI;\r
+import com.vaadin.ui.Button;\r
+import com.vaadin.ui.Button.ClickEvent;\r
+import com.vaadin.ui.Button.ClickListener;\r
+import com.vaadin.ui.Component;\r
+import com.vaadin.ui.Label;\r
+import com.vaadin.ui.Notification;\r
+import com.vaadin.ui.Notification.Type;\r
+import com.vaadin.ui.VerticalLayout;\r
+\r
+public class ErrorHandlers extends AbstractTestUI {\r
+\r
+ public static class NotificationErrorHandler implements ErrorHandler {\r
+\r
+ @Override\r
+ public void error(com.vaadin.server.ErrorEvent event) {\r
+ Notification.show(getErrorMessage(event), Type.ERROR_MESSAGE);\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ protected void setup(VaadinRequest request) {\r
+ addComponent(runtimeExceptionOnClick(new Button("Standard button")));\r
+ addComponent(npeOnClick(new Button("Standard button with NPE")));\r
+ Button customErrorButton = notificationErrorHandler(new Button(\r
+ "Button with notification error handler"));\r
+ addComponent(runtimeExceptionOnClick(customErrorButton));\r
+\r
+ final VerticalLayout layoutWithErrorHandler = new VerticalLayout(\r
+ runtimeExceptionOnClick(new Button("Error handler on parent")));\r
+ ErrorHandler e = new ErrorHandler() {\r
+\r
+ @Override\r
+ public void error(com.vaadin.server.ErrorEvent event) {\r
+ layoutWithErrorHandler.addComponent(new Label("Layout error: "\r
+ + getErrorMessage(event)));\r
+ }\r
+\r
+ };\r
+ layoutWithErrorHandler.setErrorHandler(e);\r
+ layoutWithErrorHandler\r
+ .addComponent(notificationErrorHandler(npeOnClick(new Button(\r
+ "Error handler on button and parent"))));\r
+ addComponent(layoutWithErrorHandler);\r
+ }\r
+\r
+ private Button notificationErrorHandler(Button button) {\r
+ button.setErrorHandler(new NotificationErrorHandler());\r
+ return button;\r
+ }\r
+\r
+ protected static String getErrorMessage(com.vaadin.server.ErrorEvent event) {\r
+ Component c = DefaultErrorHandler.findAbstractComponent(event);\r
+ String errorMsg = "Error: '" + getMessage(event) + "' in ";\r
+ errorMsg += c.getClass().getSimpleName() + " with caption '"\r
+ + c.getCaption() + "'";\r
+ return errorMsg;\r
+ }\r
+\r
+ private static String getMessage(com.vaadin.server.ErrorEvent event) {\r
+ Throwable e = getUserCodeException(event);\r
+ if (e.getMessage() != null) {\r
+ return e.getMessage();\r
+ } else {\r
+ return e.getClass().getSimpleName();\r
+ }\r
+ }\r
+\r
+ private static Throwable getUserCodeException(\r
+ com.vaadin.server.ErrorEvent event) {\r
+ Throwable t = event.getThrowable();\r
+ if (t instanceof RpcInvocationException) {\r
+ t = t.getCause();\r
+ }\r
+ if (t instanceof InvocationTargetException) {\r
+ t = t.getCause();\r
+ }\r
+ if (t instanceof MethodException) {\r
+ t = t.getCause();\r
+ }\r
+\r
+ return t;\r
+\r
+ }\r
+\r
+ private Button runtimeExceptionOnClick(Button customErrorButton) {\r
+ customErrorButton.setCaption("RE: " + customErrorButton.getCaption());\r
+\r
+ customErrorButton.addClickListener(new ClickListener() {\r
+\r
+ @Override\r
+ public void buttonClick(ClickEvent event) {\r
+ throw new RuntimeException("Fail in click event");\r
+ }\r
+ });\r
+ return customErrorButton;\r
+ }\r
+\r
+ private Button npeOnClick(Button customErrorButton) {\r
+ customErrorButton.setCaption("NPE: " + customErrorButton.getCaption());\r
+ customErrorButton.addClickListener(new ClickListener() {\r
+\r
+ @Override\r
+ public void buttonClick(ClickEvent event) {\r
+ Integer i = null;\r
+ i += 2;\r
+ }\r
+ });\r
+ return customErrorButton;\r
+ }\r
+\r
+ @Override\r
+ protected String getTestDescription() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ protected Integer getTicketNumber() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+}\r