[KSS-checkins] r35990 - kukit/kukit.js/trunk/kukit

reebalazs at codespeak.net reebalazs at codespeak.net
Wed Dec 27 11:23:16 CET 2006


Author: reebalazs
Date: Wed Dec 27 11:23:14 2006
New Revision: 35990

Modified:
   kukit/kukit.js/trunk/kukit/kukit.js
Log:
if a non-xml command result arrives, also analyze the X-KSSCOMMANDS response header for a payload.

This makes it possible to attach a kss 'error' command on a standard error message page.

Modified: kukit/kukit.js/trunk/kukit/kukit.js
==============================================================================
--- kukit/kukit.js/trunk/kukit/kukit.js	(original)
+++ kukit/kukit.js/trunk/kukit/kukit.js	Wed Dec 27 11:23:14 2006
@@ -225,12 +225,14 @@
 kukit.ExplicitError = kukit.ut.exceptionFactory('ExplicitError');
 kukit.ExplicitError.prototype.__superinit__ = kukit.ExplicitError.prototype.__init__;
 kukit.ExplicitError.prototype.__init__ = function(name, errorcommand) {
-    var message = 'Explicit error, reason=' + errorcommand.parms.message;
+    var message = 'Explicit error';
     var kw = this.__superinit__(name, message);
     kw.errorcommand = errorcommand;
     return kw
 };
 
+kukit.ResponseParsingError = kukit.ut.exceptionFactory('ResponseParsingError');
+
 // Backparms can be used on command execution.
 kukit.notifyServer = function(url, params, oper) {
     var sendHook = function(queueItem) {
@@ -241,7 +243,7 @@
     var timeoutHook = function(queueItem) {
         // store the queue reception on the oper
         oper.queueItem = queueItem;
-        kukit.processError(oper);
+        kukit.processError(oper, 'timeout');
     };
     kukit.requestManager.notifyServer(sendHook, url, timeoutHook);
 };
@@ -288,6 +290,8 @@
                     kukit.logFatal(msg);
                     // just throw it too...
                     throw msg;
+                } else if (e.name == 'ResponseParsingError') {
+                    kukit.processError(oper, 'Response parsing error: ' + e);
                 } else if (e.name == 'ExplicitError') {
                     kukit.processError(oper, e.errorcommand);
                 } else {
@@ -303,39 +307,75 @@
     }
 };
 
-kukit.getNsTags = function(domXml, tagName) {
-    if (domXml.getElementsByTagNameNS) { 
-        tags = domXml.getElementsByTagNameNS('http://www.kukit.org/commands/1.0',
+kukit.getNsTags = function(dom, tagName) {
+    if (dom.getElementsByTagNameNS) { 
+        tags = dom.getElementsByTagNameNS('http://www.kukit.org/commands/1.0',
             tagName);
     } else {
         //IE does not know DOM2
-        tags = domXml.getElementsByTagName('kukit:' + tagName);
+        tags = dom.getElementsByTagName('kukit:' + tagName);
     }
     return tags;
 };
 
 kukit.processResult = function(domDoc, oper) {
-    var domXml = domDoc.responseXML;
-    // for IE, an empty response is produced: we need to check the html tag
-    // On Opera, we don't even get to here: we can only catch timeouts elsewhere
-    if (domXml == null || typeof(domXml) == 'undefined' || kukit.getNsTags(domXml, 'commands').length != 1) {
-        // This will happen in case there are errors in the response
-        // Possible cases:
-        //   1. No response from server, and browser notifies us with an empty response
-        //   2. There was an error on the server, and we got an error message as response
-        // Call the error handler.
-        throw new kukit.ExplicitError();
-    }
-    // Opera <= 8.5 does not have the parseError attribute, so check for it first
-    if (domXml.parseError && (domXml.parseError != 0)) {
-        kukit.logError(Sarissa.getParseErrorText(domXml));
-        return;
+    // checking various dom process errors, and get the commands part
+    //
+    //
+    var dom;
+    var commandstags = [];
+    // Let's process xml payload first:
+    if (domDoc.responseXML) {
+        dom = domDoc.responseXML;
+        commandstags = kukit.getNsTags(dom, 'commands');
+        if (commandstags.length != 1) {
+            // no good, maybe better luck with it as html payload
+            dom = null;
+        }
+    }
+    // Check for html too, this enables setting the kss error command on the 
+    // error response.
+    if (dom == null) {
+        // Read the header and load it as xml, if defined.
+        var payload = domDoc.getResponseHeader('X-KSSCOMMANDS');
+        if (payload) {
+            var root_txt = '<?xml version="1.0"?><root xmlns:kukit="http://www.kukit.org/commands/1.0">' + payload + '</root>';
+            try {
+                dom = (new DOMParser()).parseFromString(root_txt, "text/xml");
+            } catch(e) {
+                // XXX this does not work on Opera for sure
+                //throw new kukit.ResponseParsingError('Exception: "' + e + '"');
+                throw new kukit.ResponseParsingError('Error parsing X-KSSCOMMANDS header.');
+            }
+            commandstags = kukit.getNsTags(dom, 'commands');
+            if (commandstags.length != 1) {
+                // no good
+                dom = null;
+            }
+        } else {
+            // Ok. we have not found it either in the headers.
+            // Check if there was a parsing error in the xml, and log it as reported from the dom
+            // Opera <= 8.5 does not have the parseError attribute, so check for it first
+            dom = domDoc.responseXML;
+            if (dom && dom.parseError && (dom.parseError != 0)) {
+                throw new kukit.ResponseParsingError('KSS payload not found: ' + Sarissa.getParseErrorText(dom));
+            } else {
+                throw new kukit.ResponseParsingError('KSS payload not found');
+            }
+        }
     }
-    commands = kukit.getNsTags(domXml, 'command');
+    if (dom == null) {
+        // this should not happen
+        throw new kukit.ResponseParsingError('Neither xml nor html payload.');
+    }
+    // find the commands (atm we don't limit ourselves inside the commandstag)
+    var commands = kukit.getNsTags(dom, 'command');
+    // Warning, if there is a valid response containing 0 commands.
     if (commands.length == 0) {
         kukit.logWarning('No commands in kukit response');
         return;
     }
+    // One or more valid commands to parse
     var command_processor = new kukit.CommandProcessor();
     command_processor.parseCommands(commands, domDoc);
     command_processor.executeCommands(oper);
@@ -347,8 +387,12 @@
         var error_action = oper.eventrule.actions.getErrorActionFor(oper.action);
         }
     var reason = '';
-    if (typeof(errorcommand) != 'undefined') {
-        reason = ', reason="' + errorcommand.parms.message + '" '
+    if (typeof(errorcommand) == 'string') {
+        // not a command, just a string
+        reason = ', client_reason="' + errorcommand + '" ';
+    } else if (typeof(errorcommand) != 'undefined') {
+        // a real error command, sent by the server
+        reason = ', server_reason="' + errorcommand.parms.message + '" ';
     }
     if (error_action) {
         kukit.logWarning('Request failed at url ' + oper.queueItem.url + ', rid=' + oper.queueItem.rid + reason + ', will be handled by action "' + error_action.name + '"');
@@ -405,7 +449,8 @@
         if (childNode.nodeType != 1) 
             continue;
         if (childNode.localName) {
-            if (childNode.localName.toLowerCase() != "param") {
+            // (here tolerate both cases)
+            if (childNode.localName.toLowerCase() != "param" && childNode.nodeName.toLowerCase() != "kukit:param") {
                 throw 'Bad payload, expected param';
             }
         } else {


More information about the Kukit-checkins mailing list