summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorMarc Englund <marc.englund@itmill.com>2009-01-23 09:48:33 +0000
committerMarc Englund <marc.englund@itmill.com>2009-01-23 09:48:33 +0000
commitc60ca65f8f941fe3d80317747f5dc4f41c0e70d6 (patch)
tree441a360960bf623c8940341909c0fd68e3b34d69 /src/com
parent58507aa78d79200fa9b858395daf280e00c5e86d (diff)
downloadvaadin-framework-c60ca65f8f941fe3d80317747f5dc4f41c0e70d6.tar.gz
vaadin-framework-c60ca65f8f941fe3d80317747f5dc4f41c0e70d6.zip
Added a communication error system-message that is written to the client when the initial page is rendered. If any UIDL request fails, the message is shown. Fixes [2485]
svn changeset:6624/svn branch:trunk
Diffstat (limited to 'src/com')
-rw-r--r--src/com/itmill/toolkit/Application.java59
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ApplicationConfiguration.java20
-rwxr-xr-xsrc/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java44
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java53
4 files changed, 155 insertions, 21 deletions
diff --git a/src/com/itmill/toolkit/Application.java b/src/com/itmill/toolkit/Application.java
index fa4f5e9a9d..866a9ced51 100644
--- a/src/com/itmill/toolkit/Application.java
+++ b/src/com/itmill/toolkit/Application.java
@@ -1195,6 +1195,11 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener
protected String sessionExpiredCaption = "Session Expired";
protected String sessionExpiredMessage = "Take note of any unsaved data, and <u>click here</u> to continue.";
+ protected String communicationErrorURL = null;
+ protected boolean communicationErrorNotificationEnabled = true;
+ protected String communicationErrorCaption = "Communication problem";
+ protected String communicationErrorMessage = "Take note of any unsaved data, and <u>click here</u> to continue.";
+
protected String internalErrorURL = null;
protected boolean internalErrorNotificationEnabled = true;
protected String internalErrorCaption = "Internal Error";
@@ -1245,6 +1250,36 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener
/**
* @return the URL to load on null for restart
*/
+ public String getCommunicationErrorURL() {
+ return communicationErrorURL;
+ }
+
+ /**
+ * @return true = notification enabled, false = notification disabled
+ */
+ public boolean isCommunicationErrorNotificationEnabled() {
+ return communicationErrorNotificationEnabled;
+ }
+
+ /**
+ * @return the notification caption, or null for no caption
+ */
+ public String getCommunicationErrorCaption() {
+ return (communicationErrorNotificationEnabled ? communicationErrorCaption
+ : null);
+ }
+
+ /**
+ * @return the notification message, or null for no message
+ */
+ public String getCommunicationErrorMessage() {
+ return (communicationErrorNotificationEnabled ? communicationErrorMessage
+ : null);
+ }
+
+ /**
+ * @return the URL to load on null for restart
+ */
public String getInternalErrorURL() {
return internalErrorURL;
}
@@ -1313,26 +1348,26 @@ public abstract class Application implements URIHandler, Terminal.ErrorListener
* </p>
* <p>
* The default behavior is to show a notification, and restart the
- * application the the user clicks the message. <br/>
- * Instead of restarting the application, you can set a specific URL that
- * the user is taken to.<br/>
- * Setting both caption and message to null will restart the application (or
- * go to the specified URL) without displaying a notification.
- * set*NotificationEnabled(false) will achieve the same thing.
+ * application the the user clicks the message. <br/> Instead of restarting
+ * the application, you can set a specific URL that the user is taken
+ * to.<br/> Setting both caption and message to null will restart the
+ * application (or go to the specified URL) without displaying a
+ * notification. set*NotificationEnabled(false) will achieve the same thing.
* </p>
* <p>
* The situations are:
* <li>Session expired: the user session has expired, usually due to
* inactivity.</li>
+ * <li>Communication error: the client failed to contact the server, or the
+ * server returned and invalid response.</li>
* <li>Internal error: unhandled critical server error (e.g out of memory,
* database crash)
* <li>Out of sync: the client is not in sync with the server. E.g the user
- * opens two windows showing the same application, and makes changes in one
- * of the windows - the other window is no longer in sync, and (for
- * instance) pressing a button that is no longer present in the UI will
- * cause a out-of-sync -situation. You might want to disable the
- * notification if silently ignoring a action (e.g button press) is not a
- * problem in your application.
+ * opens two windows showing the same application, but the application does
+ * not support this and uses the same Window instance. When the user makes
+ * changes in one of the windows - the other window is no longer in sync,
+ * and (for instance) pressing a button that is no longer present in the UI
+ * will cause a out-of-sync -situation.
* </p>
*/
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConfiguration.java b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConfiguration.java
index 3fe4015b9d..919ab0807c 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConfiguration.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConfiguration.java
@@ -14,6 +14,9 @@ public class ApplicationConfiguration {
private String appUri;
private JavaScriptObject versionInfo;
private String windowName;
+ private String communicationErrorCaption;
+ private String communicationErrorMessage;
+ private String communicationErrorUrl;
private static ArrayList<ApplicationConnection> unstartedApplications = new ArrayList<ApplicationConnection>();
private static ArrayList<ApplicationConnection> runningApplications = new ArrayList<ApplicationConnection>();
@@ -50,6 +53,18 @@ public class ApplicationConfiguration {
return versionInfo;
}
+ public String getCommunicationErrorCaption() {
+ return communicationErrorCaption;
+ }
+
+ public String getCommunicationErrorMessage() {
+ return communicationErrorMessage;
+ }
+
+ public String getCommunicationErrorUrl() {
+ return communicationErrorUrl;
+ }
+
private native void loadFromDOM()
/*-{
@@ -69,6 +84,11 @@ public class ApplicationConfiguration {
if(jsobj.versionInfo) {
this.@com.itmill.toolkit.terminal.gwt.client.ApplicationConfiguration::versionInfo = jsobj.versionInfo;
}
+ if(jsobj.comErrMsg) {
+ this.@com.itmill.toolkit.terminal.gwt.client.ApplicationConfiguration::communicationErrorCaption = jsobj.comErrMsg.caption;
+ this.@com.itmill.toolkit.terminal.gwt.client.ApplicationConfiguration::communicationErrorMessage = jsobj.comErrMsg.message;
+ this.@com.itmill.toolkit.terminal.gwt.client.ApplicationConfiguration::communicationErrorUrl = jsobj.comErrMsg.url;
+ }
} else {
$wnd.alert("Toolkit app failed to initialize: " + this.id);
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
index e9f4f1597b..d8dd3a5895 100755
--- a/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
@@ -328,12 +328,13 @@ public class ApplicationConnection {
if (!forceSync) {
final RequestBuilder rb = new RequestBuilder(RequestBuilder.POST,
uri);
+ // TODO enable timeout
+ // rb.setTimeoutMillis(timeoutMillis);
rb.setHeader("Content-Type", "text/plain;charset=utf-8");
try {
rb.sendRequest(requestData, new RequestCallback() {
public void onError(Request request, Throwable exception) {
- // TODO Better reporting to user
- console.error("Got error");
+ showCommunicationError(exception.getMessage());
endRequest();
if (!applicationRunning) {
// start failed, let's try to start the next app
@@ -343,6 +344,16 @@ public class ApplicationConnection {
public void onResponseReceived(Request request,
Response response) {
+ console.log("Server visit took "
+ + String.valueOf((new Date()).getTime()
+ - requestStartTime.getTime()) + "ms");
+
+ switch (response.getStatusCode()) {
+ case 0:
+ showCommunicationError("Invalid status code 0 (server down?)");
+ return;
+ // TODO could add more cases
+ }
if ("init".equals(uidl_security_key)) {
// Read security key
String key = response
@@ -351,9 +362,6 @@ public class ApplicationConnection {
uidl_security_key = key;
}
}
- console.log("Server visit took "
- + String.valueOf((new Date()).getTime()
- - requestStartTime.getTime()) + "ms");
if (applicationRunning) {
handleReceivedJSONMessage(response);
} else {
@@ -405,6 +413,30 @@ public class ApplicationConnection {
}
}
+ /**
+ * Shows the communication error notification. The 'details' only go to the
+ * console for now.
+ *
+ * @param details
+ * Optional details for debugging.
+ */
+ private void showCommunicationError(String details) {
+ console.error("Communication error: " + details);
+ String html = "";
+ if (configuration.getCommunicationErrorCaption() != null) {
+ html += "<h1>" + configuration.getCommunicationErrorCaption()
+ + "</h1>";
+ }
+ if (configuration.getCommunicationErrorMessage() != null) {
+ html += "<p>" + configuration.getCommunicationErrorMessage()
+ + "</p>";
+ }
+ INotification n = new INotification(1000 * 60 * 45);
+ n.addEventListener(new NotificationRedirect(configuration
+ .getCommunicationErrorUrl()));
+ n.show(html, INotification.CENTERED_TOP, INotification.STYLE_SYSTEM);
+ }
+
private native void syncSendForce(JavaScriptObject xmlHttpRequest,
String uri, String requestData)
/*-{
@@ -551,7 +583,7 @@ public class ApplicationConnection {
json = JSONParser.parse(jsonText);
} catch (final com.google.gwt.json.client.JSONException e) {
endRequest();
- console.log(e.getMessage() + " - Original JSON-text:");
+ showCommunicationError(e.getMessage() + " - Original JSON-text:");
console.log(jsonText);
return;
}
diff --git a/src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java b/src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java
index d442b1ed17..471ef2877e 100644
--- a/src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java
+++ b/src/com/itmill/toolkit/terminal/gwt/server/ApplicationServlet.java
@@ -784,7 +784,8 @@ public class ApplicationServlet extends HttpServlet {
*/
private void writeAjaxPage(HttpServletRequest request,
HttpServletResponse response, Window window, String themeName,
- Application application) throws IOException, MalformedURLException {
+ Application application) throws IOException, MalformedURLException,
+ ServletException {
// e.g portlets only want a html fragment
boolean fragment = (request.getAttribute(REQUEST_FRAGMENT) != null);
@@ -885,6 +886,15 @@ public class ApplicationServlet extends HttpServlet {
// but indicates that it should not be used in CSS and such:
appId = appId + appId.hashCode();
+ // Get system messages
+ Application.SystemMessages systemMessages = null;
+ try {
+ systemMessages = getSystemMessages();
+ } catch (SystemMessageException e) {
+ // failing to get the system messages is always a problem
+ throw new ServletException("CommunicationError!", e);
+ }
+
if (isGecko17(request)) {
// special start page for gecko 1.7 versions. Firefox 1.0 is not
// supported, but the hack is make it possible to use linux and
@@ -923,7 +933,25 @@ public class ApplicationServlet extends HttpServlet {
page.write(VERSION);
page.write("\",applicationVersion:\"");
page.write(application.getVersion());
- page.write("\"}");
+ page.write("\"},");
+ if (systemMessages != null) {
+ // Write the CommunicationError -message to client
+ String caption = systemMessages.getCommunicationErrorCaption();
+ if (caption != null) {
+ caption = "\"" + caption + "\"";
+ }
+ String message = systemMessages.getCommunicationErrorMessage();
+ if (message != null) {
+ message = "\"" + message + "\"";
+ }
+ String url = systemMessages.getCommunicationErrorURL();
+ if (url != null) {
+ url = "\"" + url + "\"";
+ }
+ page.write("\"comErrMsg\": {" + "\"caption\":" + caption + ","
+ + "\"message\" : " + message + "," + "\"url\" : " + url
+ + "}");
+ }
page.write("};\n//]]>\n</script>\n");
if (themeName != null) {
@@ -978,7 +1006,26 @@ public class ApplicationServlet extends HttpServlet {
page.write(VERSION);
page.write("\",applicationVersion:\"");
page.write(application.getVersion());
- page.write("\"}");
+ page.write("\"},");
+ if (systemMessages != null) {
+ // Write the CommunicationError -message to client
+ String caption = systemMessages.getCommunicationErrorCaption();
+ if (caption != null) {
+ caption = "\"" + caption + "\"";
+ }
+ String message = systemMessages.getCommunicationErrorMessage();
+ if (message != null) {
+ message = "\"" + message + "\"";
+ }
+ String url = systemMessages.getCommunicationErrorURL();
+ if (url != null) {
+ url = "\"" + url + "\"";
+ }
+
+ page.write("\"comErrMsg\": {" + "\"caption\":" + caption + ","
+ + "\"message\" : " + message + "," + "\"url\" : " + url
+ + "}");
+ }
page.write("};\n//]]>\n</script>\n");
if (themeName != null) {