Thursday, June 05, 2008

On AJAX problems with prototype.js v1.5+ (till 1.6.0.2 at least)

My (a little tiring now) work on JOnto 2.0 is getting closer to the finish line. I can almost see the crowd cheering.
Many changes, including WordNet in RDF/OWL and OpenThesaurus (non-English thesauri) support, full-text index, etc.

I decided to check the current version (let’s call it JOnto 2.0 PR 1) with the most recent prototype.js.

To my surprise it did not work. Hanged with no logs whatsoever (as usually with prototype.js).
The bug was not, however, in my code.
It took me a while to recall the details of this deja-vu feeling.

To make sure I will not forget it next time, and for other people to know what is going wrong, here a short description:

If you catch exception with onException(resp, ex) you will see that your script is trying to perform illegal operation.
Firebug reports “Component returned failure code: 0x80070057”
Safari is a little more precise - reports problems with an attempt to set illegal header in the HTTP request.

Where is the bug?

Apparently since prototype.js v1.5, i.e., the first time I have discovered it (since it worked in v1.4) the setRequestHeaders method uses following implementation:

for (var name in headers)
this.transport.setRequestHeader(name, headers[name]);

which does not catch any exceptions

My fix is the following, change this two lines to

var transport = this.transport;
$H(headers).each(
function (header){
        
try{
                 transport.setRequestHeader(header.key, header.value);
        }
catch(ex){
//                 YAHOO.log(header.key, header.value, ex);
        }
});

The question remains how is that possible that some invocations of Ajax.Request do and some don’t produce this problem.
For now - I’d rather patch the script and live on.