aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur <artur@vaadin.com>2017-01-02 11:10:33 +0200
committerPekka Hyvönen <pekka@vaadin.com>2017-01-02 11:10:33 +0200
commit86ed6cc475d9e9ee79fee4f2340c271ffa5c702e (patch)
tree94ee81c7c0747a53cc526d93ac5614a59326de90
parent04febccaad259f78916cce6c447707dc3e1eb83d (diff)
downloadvaadin-framework-86ed6cc475d9e9ee79fee4f2340c271ffa5c702e.tar.gz
vaadin-framework-86ed6cc475d9e9ee79fee4f2340c271ffa5c702e.zip
Call error handler for exceptions in UI.init() (#8055)
Fixes #4995
-rw-r--r--server/src/main/java/com/vaadin/server/communication/UIInitHandler.java13
-rw-r--r--server/src/test/java/com/vaadin/server/communication/ServletUIInitHandlerTest.java188
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/ui/UIInitException.java10
-rw-r--r--uitest/src/test/java/com/vaadin/tests/components/ui/UIInitExceptionTest.java4
4 files changed, 210 insertions, 5 deletions
diff --git a/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java b/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java
index f66dbe4107..aa167d137f 100644
--- a/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java
+++ b/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java
@@ -211,10 +211,17 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
// Set thread local here so it is available in init
UI.setCurrent(ui);
- ui.doInit(request, uiId.intValue(), embedId);
-
+ Exception initException = null;
+ try {
+ ui.doInit(request, uiId.intValue(), embedId);
+ } catch (Exception e) {
+ initException = e;
+ }
session.addUI(ui);
-
+ if (initException != null) {
+ ui.getSession().getCommunicationManager()
+ .handleConnectorRelatedException(ui, initException);
+ }
// Warn if the window can't be preserved
if (embedId == null
&& vaadinService.preserveUIOnRefresh(provider, event)) {
diff --git a/server/src/test/java/com/vaadin/server/communication/ServletUIInitHandlerTest.java b/server/src/test/java/com/vaadin/server/communication/ServletUIInitHandlerTest.java
new file mode 100644
index 0000000000..6c61922307
--- /dev/null
+++ b/server/src/test/java/com/vaadin/server/communication/ServletUIInitHandlerTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2000-2016 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.communication;
+
+import java.io.IOException;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.vaadin.server.DefaultDeploymentConfiguration;
+import com.vaadin.server.ErrorEvent;
+import com.vaadin.server.ErrorHandler;
+import com.vaadin.server.LegacyCommunicationManager;
+import com.vaadin.server.MockServletConfig;
+import com.vaadin.server.UIClassSelectionEvent;
+import com.vaadin.server.UICreateEvent;
+import com.vaadin.server.UIProvider;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinServlet;
+import com.vaadin.server.VaadinServletRequest;
+import com.vaadin.server.VaadinServletResponse;
+import com.vaadin.server.VaadinServletService;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.ui.UI;
+
+public class ServletUIInitHandlerTest {
+
+ public static class CommunicationMock {
+
+ public final UI ui;
+ public final ServletConfig servletConfig;
+ public final VaadinServlet servlet;
+ public final DefaultDeploymentConfiguration deploymentConfiguration;
+ public final VaadinServletService service;
+ public final AlwaysLockedVaadinSession session;
+
+ public CommunicationMock(final UI ui) throws Exception {
+ servletConfig = new MockServletConfig();
+ servlet = new VaadinServlet();
+ servlet.init(servletConfig);
+
+ deploymentConfiguration = new DefaultDeploymentConfiguration(
+ UI.class, new Properties());
+
+ service = new VaadinServletService(servlet,
+ deploymentConfiguration);
+ session = new AlwaysLockedVaadinSession(service);
+ LegacyCommunicationManager communicationManager = new LegacyCommunicationManager(
+ session);
+ session.setCommunicationManager(communicationManager);
+ session.setConfiguration(deploymentConfiguration);
+ session.addUIProvider(new UIProvider() {
+
+ @Override
+ public Class<? extends UI> getUIClass(
+ UIClassSelectionEvent event) {
+ return ui.getClass();
+ }
+
+ @Override
+ public UI createInstance(UICreateEvent event) {
+ return ui;
+ }
+ });
+ this.ui = ui;
+ }
+
+ public VaadinRequest createInitRequest() {
+ return new VaadinServletRequest(
+ Mockito.mock(HttpServletRequest.class), service) {
+ @Override
+ public String getMethod() {
+ return "POST";
+ }
+
+ @Override
+ public String getParameter(String name) {
+ if (UIInitHandler.BROWSER_DETAILS_PARAMETER.equals(name)) {
+ return "1";
+ }
+ return super.getParameter(name);
+ }
+
+ };
+ }
+
+ }
+
+ @Test
+ public void errorHandlerForInitException() throws Exception {
+ final AtomicInteger pre = new AtomicInteger(0);
+ final AtomicInteger errorHandlerCalls = new AtomicInteger(0);
+
+ UI ui = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ pre.incrementAndGet();
+ throw new RuntimeException("Exception produced in init()");
+ }
+ };
+
+ ui.setErrorHandler(new ErrorHandler() {
+ @Override
+ public void error(ErrorEvent event) {
+ errorHandlerCalls.incrementAndGet();
+ }
+ });
+
+ CommunicationMock mock = new CommunicationMock(ui);
+ VaadinRequest initRequest = mock.createInitRequest();
+
+ ServletUIInitHandler servletUIInitHandler = new ServletUIInitHandler();
+ servletUIInitHandler.handleRequest(mock.session, initRequest,
+ new VaadinServletResponse(
+ Mockito.mock(HttpServletResponse.class), mock.service) {
+ @Override
+ public ServletOutputStream getOutputStream()
+ throws IOException {
+ return new ServletOutputStream() {
+ @Override
+ public void write(int b) throws IOException {
+ }
+ };
+ }
+ });
+
+ Assert.assertEquals(1, pre.getAndIncrement());
+ Assert.assertEquals(1, errorHandlerCalls.getAndIncrement());
+ Assert.assertEquals(mock.session, ui.getSession());
+ }
+
+ @Test
+ public void initExceptionNoErrorHandler() throws Exception {
+ final AtomicInteger pre = new AtomicInteger(0);
+
+ UI ui = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ pre.incrementAndGet();
+ throw new RuntimeException("Exception produced in init()");
+ }
+ };
+
+ CommunicationMock mock = new CommunicationMock(ui);
+ VaadinRequest initRequest = mock.createInitRequest();
+
+ ServletUIInitHandler servletUIInitHandler = new ServletUIInitHandler();
+ servletUIInitHandler.handleRequest(mock.session, initRequest,
+ new VaadinServletResponse(
+ Mockito.mock(HttpServletResponse.class), mock.service) {
+ @Override
+ public ServletOutputStream getOutputStream()
+ throws IOException {
+ return new ServletOutputStream() {
+ @Override
+ public void write(int b) throws IOException {
+ }
+ };
+ }
+ });
+
+ Assert.assertEquals(1, pre.getAndIncrement());
+ // Default error handler only logs the exception
+ Assert.assertEquals(mock.session, ui.getSession());
+ }
+
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/ui/UIInitException.java b/uitest/src/main/java/com/vaadin/tests/components/ui/UIInitException.java
index d5f26ade29..fa25d7e837 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/ui/UIInitException.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/ui/UIInitException.java
@@ -1,12 +1,22 @@
package com.vaadin.tests.components.ui;
+import com.vaadin.server.ErrorHandler;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Label;
public class UIInitException extends AbstractTestUI {
@Override
protected void setup(VaadinRequest request) {
+ setErrorHandler(new ErrorHandler() {
+ @Override
+ public void error(com.vaadin.server.ErrorEvent event) {
+ addComponent(new Label("An exception occurred: "
+ + event.getThrowable().getMessage()));
+
+ }
+ });
throw new RuntimeException("Catch me if you can");
}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/ui/UIInitExceptionTest.java b/uitest/src/test/java/com/vaadin/tests/components/ui/UIInitExceptionTest.java
index c1d6aaa55b..064132d4c7 100644
--- a/uitest/src/test/java/com/vaadin/tests/components/ui/UIInitExceptionTest.java
+++ b/uitest/src/test/java/com/vaadin/tests/components/ui/UIInitExceptionTest.java
@@ -3,9 +3,9 @@ package com.vaadin.tests.components.ui;
import org.junit.Assert;
import org.junit.Test;
-import com.vaadin.tests.tb3.MultiBrowserTest;
+import com.vaadin.tests.tb3.SingleBrowserTest;
-public class UIInitExceptionTest extends MultiBrowserTest {
+public class UIInitExceptionTest extends SingleBrowserTest {
@Test
public void testExceptionOnUIInit() throws Exception {
openTestURL();