5

I have looked at the following thread

jQuery Ajax - Status Code 0?

However I could not find a definitive answer and I am having serious trouble trying to find the source of my issue so I am posting here in the hopes that someone can point me in the right direction.

In my code I am performing an Angular HTTP post which just sends basic JSON data, then within the on success callback I am using AJAX to upload files to the same server. (I know I should not be using jQuery and Angular however I can't change this for the moment)

It looks something like this

 var deferred = $q.defer()

 // first post
 $http.post(url,payload,{params: params, headers: headers)
   .then(function(response) {

    uploadFiles(response,deferred);
    // I am also sending google analytics events here

   }, function(error) {
      // do error stuff
   }

  return deferred.promise;

 // upload files function
 function uploadFiles(response,deferred){

 $ajax({
   type: 'POST',
   processData: false,
   contentType: false,
   data: data // this new FormData() with files appended to it,
   url: 'the-endpoint-for-the-upload',
   dataType: 'json',
   success: function(data) {
     // do success stuff here
    deferred.resolve(data);
   },
   error: function(jqXHR, textStatus, errorThrown) {

            var message = {};

            if (jqXHR.status === 0) {
              message.jqXHRStatusIsZero = "true";
            }

            if (jqXHR.readyState === 0) {
              message.jqXHRReadyStateIsZero = "true";
            }

            if (jqXHR.status === '') {
              message.jqXHRStatusIsEmptyString = "true";
            }

            if (jqXHR.status) {
              message.jqXHRStatus = jqXHR.status; 
            }

            if (jqXHR.readyState) {
              message.jqXHRReadyState = jqXHR.readyState;
            }

            if (jqXHR.responseText) {
              message.jqXHR = jqXHR.responseText; 
            }

            if (textStatus) {
              message.textStatus = textStatus;
            }

            if (errorThrown) {
              message.errorThrown = errorThrown;
            }

            message.error = 'HTTP file upload failed';

            logError(message);

            deferred.resolve(message);
      }
  }
})

}

Not my exact code but almost the exact same.

The issue is that is works almost all of the time, but maybe three or four in every few hundred will fail. By fail I mean the error handler function is called on the file upload function and the files are not uploaded.

I get jqXHRStatus 0 and jqXHRReadyState 0 when this occurs.

The only way I am able to replicate the issue is by hitting the refresh on the browser when the request is being processed, however users have advised they are not doing this (although have to 100% confirm this)

Is there perhaps a serious flaw in my code which I am not seeing? Maybe passing deferred variable around isn't good practice? Or another way the ajax request is being cancelled that I am not considering? Could sending google analytics events at the same time be interfering?

Any advice would be great and please let me know if you would like more information on the issue.

Community
  • 1
  • 1
user2085143
  • 4,162
  • 7
  • 39
  • 68
  • 1
    It may happen if page is switched during request or maybe if it is not fully loaded and the request already begins? It may happen if data is not o.k.? Is some event fired which may break the request? You sure nothing of this is true? Because something must break the request while its processing I guess. – Blackbam May 16 '17 at 13:51
  • how do you handle back-end errors? Maybe show backend code too – alepeino May 16 '17 at 14:14
  • you may get more information if you view the browsers devtools console when you replicate the issue is by hitting the refresh on the browser. The Network tab may have further information as well (XHR option) – KorreyD May 16 '17 at 23:22
  • Can you create a jsfiddle https://jsfiddle.net to reproduce issue? – guest271314 May 17 '17 at 00:04
  • Could you see your html code on the form? please – Snoozer May 17 '17 at 09:02

2 Answers2

2

This means, the request has been canceled.

There could be many different reasons for that, but be aware: this could be also due to a browser bug or issue - so i believe (IMHO) there is no way to prevent this kind of issues.

Think for example, you get a 503 (Service Unavailable) response. What you would do in such a case? This is also a sporadic and not predictable issue. Just live with that, and try to repost your data.

Without reinventing the wheel, I suggest you to implement: Retrying ajax calls using the deferred api

deblocker
  • 7,629
  • 2
  • 24
  • 59
0

My guess is that your code is executing before it actually gets back from the call. I.e. the call goes back and nothing was returned and it gives a 0 error. This would make sense as the error is variable. Most of the time it would return fine because the backend executed fast enough but sometimes it wouldn't because it took especially long or something else happened etc. Javascript doesn't ever REALLY stop execution. It says it does but especially passing between angular and jquery with multiple ajax requests it wouldn't be surprising if it was executing the second ajax call before it actually completed your angular post. That's why a refresh would replicate the error because it's would clear your variables.

Some things you can do to test this:

  1. On the backend make a timer that goes for a few seconds before it returns anything. This will probably make your code fail more consistently.

  2. Set breakpoints and see when they are being hit and the values they contain in the javascript.

Good luck!