In #995854-58: #ajax doesn't work at all if a file element (or enctype => "multipart/form-data") is included in the form, both sun (#64) and I noticed in testing a situation in Drupal.ajaxError where the xmlhttp.statusText or xmlhttp.responseText were not populated in the object. Therefore, as Drupal.ajaxError attempted to process them, it created an unhandled exception itself.

This patch resolves that error path, which could be a particularly nasty one, especially since this extended error checking was explicitly put here to help us *track down* "AJAX statusCode = 0" problems.

How to recreate the original problem:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rfay’s picture

Status: Active » Needs review
effulgentsia’s picture

subscribe. haven't thought about this enough yet to comment. curious what sun thinks.

rfay’s picture

Just FYI, the reason for the two separate try/catch blocks is that we might conceivably have info in one of the object members but not in the other.

tstoeckler’s picture

+++ misc/drupal.js
@@ -314,8 +314,22 @@ Drupal.ajaxError = function (xmlhttp, uri) {
+  ¶

Minor: Trailing whitespace.

Powered by Dreditor.

rfay’s picture

This removes the trailing whitespace.

I discovered that I had eclipse configured (forever) to remove trailing whitespace on PHP, but it wasn't doing it for JS. So I will annoy sun less in the future :-)

I would *really* like to get this in before launch, because it potentially may affect our ability to resolve AJAX problems when they occur. I'd love for D7 to have 50% fewer "AJAX Error 0 has occurred" issue filings :-) And for the ones that get filed to actually be understandable.

aspilicious’s picture

I used my premature js/programmer skills to give this a review.
This code *only* puts a try catch block around responseText and statusText.

Without this patch
- if statusText or responseText throw an error, we will leave this function till we find a catch

With this patch
- if responseText throws an exception, it will be catched emediatly and we still can fetch the statustext. Which has more usefull information than the previous error.

The only concern I had was that statusText and responseText may not be initialised if they throw an error. But rfay initialises them before the try catch blocks.

I can't think of any way this could break something.

effulgentsia’s picture

Status: Needs review » Reviewed & tested by the community

This could probably be bikeshed a bit, and it would be nice to understand a little more clearly why testing for statusText or responseText throws an exception, but such bikeshedding and further probing can happen after 7.0 is released. I agree with rfay that catching these remaining exceptions and alerting them (as we do for all other AJAX error paths) is better than letting them happen silently, or get alerted by the browser as some cryptic "AJAX Error 0 has occurred" message. And that it's better to get this in before 7.0 is released, so that better issue reports get filed when something does go wrong.

Kiphaas7’s picture

Is it still possible to have a reliable test case? I tried the steps in the OP, but wasn't able to get the error. I did get the race condition if I double-clicked the button, making a regular form submit, but didn't get the aborted POST in firebug.

* Checked out a fresh HEAD install, so didn't apply because #995854 got committed (though the patch mentioned in the OP is #58 and that isn't the exact patch that got committed.
* Installed Examples Project
* Enable AJAX Example
* Went to examples/ajax_example/submit_driven_ajax and press the submit button
* "You will notice that the page submits instead of an AJAX submit happening. If you look in firebug, you'll see an aborted POST response.". No it didn't, it just made a successful AJAX submit, only if I clicked while it was doing an AJAX POST, it would do a regular POST, but I believe that is a different bug.

rfay’s picture

@Kiphaas7, you could do it with the exact procedure above in the initial report, but you'd have to use an older commit level (before the actual commit that went in for that issue). However, that's not really the point. The point is that there is a way to get an exception that causes total loss of information (and interrupts js execution).

Thanks,
-Randy

webchick’s picture

Status: Reviewed & tested by the community » Fixed

This seems like a pretty solid robustifying of error handling here.

Committed to HEAD. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.