#560 bug
Seth Ladd

Ajax onSuccess Can Be Called with Response Still In Loading State

Reported by Seth Ladd | February 21st, 2009 @ 02:46 AM | in After 1.7

I have attached some screenshots that show an intermittent problem I am experiencing.

Sometimes, perhaps 10% of the time with this application, the onSuccess callback is called with a response that is still in the Loading state and with an empty responseText.

It's my understanding that this can never happen.

This is in Firefox 3.0.6 on Mac OS 10.5.6 and Firebug 1.3.2. I've also tested with Firebug disabled, but I still experience the issue.

Comments and changes to this ticket

  • Seth Ladd
  • Seth Ladd

    Seth Ladd February 21st, 2009 @ 02:47 AM

    this screenshot shows that results are certainly coming back.

  • Seth Ladd

    Seth Ladd February 21st, 2009 @ 03:19 AM

    Sorry, wanted to mention that I am definitely using Prototype 1.6.0.3

  • Seth Ladd

    Seth Ladd February 21st, 2009 @ 03:24 AM

    For the record, I seemed to have worked around the issue with this:

    @@@javascript

            onSuccess: function(response) {
                // see http://prototype.lighthouseapp.c...
                wizard.report = response.responseJSON || response._getResponseJSON();
                if (!wizard.report) {
                    alert('Client did not receive a near miss report from the server. Please reload the page and try again.');
                }
                wizard.nextButton.enable();
                wizard.cardPanel.getLayout().setActiveItem(nextPage);
                wizard.pageListCombo.setValue(nextPage);
            }
    
    
    
    
  • Seth Ladd

    Seth Ladd February 21st, 2009 @ 03:25 AM

    hm, can't seem to be able to edit a comment.

    Anyway, notice the response.responseJSON || response._getResponseJSON()

    Even though the response object comes into onSuccess with a readyState of 1 (sometimes) the internal transport is actually at ready state 4 and this has the response content.

  • Andrew Dupont

    Andrew Dupont February 22nd, 2009 @ 05:28 AM

    • Assigned user set to “Tobie Langel”
    • State changed from “new” to “bug”

    This sounds like it could be a bug with how our Ajax.Response class wraps the native XHR object. Tobie, could you have a look?

  • Tobie Langel

    Tobie Langel February 23rd, 2009 @ 09:51 AM

    I re-read through the src code, and I really don't see how this is possible, unless Firefox actually sets it's readyState too early.

    I'll look into this.

  • Seth Ladd

    Seth Ladd February 23rd, 2009 @ 09:30 PM

    • Assigned user cleared.

    I know, it sounds weird and seems impossible (we also walked through the code) so we also wonder if we've exposed a Firefox bug.

    We can certainly refactor this code to ensure this apparent race condition isn't exposed. For instance, the call to responseJSON should actually be a method call, which, when called, would check the ready state, check the response content, and attempt to parse the contents into JSON. This parsing results would be cached for the lifetime of the Ajax.Response object.

    In other words, don't do it in the constructor.

  • Tobie Langel

    Tobie Langel February 24th, 2009 @ 12:19 AM

    • Assigned user set to “Tobie Langel”

    For instance, the call to responseJSON should actually be a method call, which, when called, would check the ready state, check the response content, and attempt to parse the contents into JSON

    If you check the src code, that's exactly what happens.

  • Seth Ladd

    Seth Ladd February 24th, 2009 @ 04:21 AM

    That's weird... responseJSON is an instance variable, set on line 1379 or prototype.js (1.6.0.3)

    
        if(readyState == 4) {
          var xml = transport.responseXML;
          this.responseXML  = Object.isUndefined(xml) ? null : xml;
          this.responseJSON = this._getResponseJSON();
        }
    

    I know that _getResponseJSON() is a method call, but it would appear that it's supposed to be an internal method.

  • Tobie Langel

    Tobie Langel February 24th, 2009 @ 08:39 AM

    Yes, indeed, but all the steps you mention are taken each time a callback is called.

    Just to clarify: currently, the Ajax.Response is a throwable wrapper object created (constructed, if you prefer) each time a callback is called. (That will be modified asap, but is the current behaviour, reason why I really do not understand this bug).

  • Seth Ladd

    Seth Ladd February 24th, 2009 @ 08:42 AM

    No doubt, but I think that's part of the bug. Right before a callback is called, a new Ajax.Response is created, which inspects the transport.readyState (or whatever it is, I forget now). Somehow, who knows, it's back to 1, which does NOT trigger the parsing of the JSON.

    My suggestion to work around whatever bizarre browser bug I've exposed is to turn reponseJSON into a method (e.g. getResponseJSON()) which, when it is called, will do the work of inspecting the ready state, parse the response into JSON, etc.

    This would appear to avoid whatever weird race condition I'm running into here.

  • Tobie Langel

    Tobie Langel February 24th, 2009 @ 09:01 AM

    Basically, what you are suggesting, is that Firefox actually jumps back it's readyState from 4 to 1 at some point. Do you have evidence of this ?

    If that's really the case, then we should have our own index which we auto-increment, rather then rely on readyState.

  • Seth Ladd

    Seth Ladd February 24th, 2009 @ 07:56 PM

    Tobie,

    Sure, see the screenshot from the original comment/issue description. It shows that the transport has a ready state of 4 while the Ajax.Response has a ready state of 1.

    Very weird.

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 01:54 AM

    • Tag changed from ajax, bug, firefox, onsuccess to firefox, section:ajax

    [not-tagged:"ajax" tagged:"section:ajax" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 03:57 AM

    • Tag changed from firefox, section:ajax to section:ajax

    [not-tagged:"firefox" bulk edit command]

  • T.J. Crowder

    T.J. Crowder November 16th, 2009 @ 04:50 PM

    • Assigned user cleared.

    [responsible:none bulk edit command]

  • Chris

    Chris March 30th, 2011 @ 01:17 PM

    I'm currently experiencing the exact same problem. With firefox the Request seems to fail randomly and the onSuccess method is called but the readyState of the response is 1 instead of 4. Has this been fixed? Or is there a workaround?

  • Andrew Dupont

    Andrew Dupont May 17th, 2011 @ 03:42 AM

    • Milestone set to After 1.7
    • Importance changed from “” to “Low”

    No fix yet; I'm tentatively calling this a 1.8 fix, as that's when a handful of Ajax issues are due to be resolved.

    In the meantime, if the conversation above reflects your situation as well, you should be able to compare the response object's readyState to the "real" readyState — the response object has a transport property which points to the native XHR object. At least then you'd be able to return early from onSuccess if you discover the two readyStates are in disagreement.

  • Jason Westbrook
  • Gustavo Lo

    Gustavo Lo March 30th, 2016 @ 01:39 PM

    Thanks for the info i need this to fix my account :D, thanks a lot :)

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

The Prototype JavaScript library.

Shared Ticket Bins

Referenced by

Pages