ember-ajax icon indicating copy to clipboard operation
ember-ajax copied to clipboard

The server returned an empty string for GET

Open ArtOfSettling opened this issue 8 years ago • 16 comments

Our server is not something we can modify, and seems to return an empty string for a get with a certain EndPoint. Whilst this only shows in the console as an error, an exception is thrown which causes execution to skip through our catch block.

Everything works ok, the backend performs the work and returns as it always does, however I need a better way to handle and parse this error. Any suggestions?

  this.get('ajax').request('/users/restorepassword/' + this.get('username'), {})
    .then(function() {
      _this.set('infoMessage', 'Please check your email!');
      _this.set('errorMessage', '');
    })
    .catch(function(error) {
      // Execution reaches here, everything is ok, the server returns 200 (with an empty string)
      _this.set('infoMessage', '');
      _this.set('errorMessage', error);
    });

ArtOfSettling avatar Sep 12 '16 16:09 ArtOfSettling

Interesting. I'll try to determine why an empty string is interpreted as an error and see if we can fix that.

In the meantime, I would need a stack trace of the error in order to direct you to the correct methods to overwrite/modify.

alexlafroscia avatar Sep 14 '16 17:09 alexlafroscia

I'll fire it up here when I get a chance, in the mean time, you can spoof it pretty easily using ember-pretender. (Both my test and runtime code fail with the same error).

The key being, I guess the get and the empty string, if I change it to "{}", it does indeed work correctly, but that doesn't help me much since I'm not able to modifying the server. :)

  var server = new Pretender(function() {
    this.get("/restorepassword/:name", function() {
      return [
        200,
        {'content-type': 'application/javascript'},
        "" // <------- This being the key
      ];
    });
  });

  visit('/resetpassword');
  fillIn('#username', 'Terry');

  click('button:contains(Reset)');

  return wait().then(function() {
    assert.equal(find('.alert-info').length, 1, 'should see info after a correct password restore');
  });```

ArtOfSettling avatar Sep 14 '16 18:09 ArtOfSettling

Right, that's what I was planning to do to go about fixing it; create a regression test with that setup and work from there. Thanks for confirming that that will reproduce the problem, though!

alexlafroscia avatar Sep 14 '16 19:09 alexlafroscia

Yeah, sorry that I couldn't be of more help, I'm not at my main machine right now, if I get back there before you get back to me here, I'll post a call stack ;)

ArtOfSettling avatar Sep 14 '16 19:09 ArtOfSettling

Sure thing. I'll try to take a look at this in the next few days; as long as I can reproduce in a test, then I don't need the call stack.

alexlafroscia avatar Sep 14 '16 20:09 alexlafroscia

Hey @alexlafroscia

Any movement on this?

  • T

ArtOfSettling avatar Sep 30 '16 08:09 ArtOfSettling

No, sorry. Totally lost track of this, it's slipped my mind. I'll try to take a look soon, but would greatly appreciate a PR if you have the time yourself!

My guess is that we're trying to do JSON.parse on an empty string, which would thrown an exception. Not sure if that's the problem, but I'd be willing to bet that that's it.

alexlafroscia avatar Oct 03 '16 17:10 alexlafroscia

So, I looked into this more. I'm pretty sure that the error is actually down in jQuery, not ember-ajax. I made a failing test, but the stack trace lands somewhere in jQuery land.

Can you verify that making a request to that stubbed endpoint (just returning a strong) work in jQuery without ember-ajax?

alexlafroscia avatar Oct 11 '16 04:10 alexlafroscia

Hey! Sorry for not sorting you out with a PR, I've been a bit too busy to look back into this issue. To somewhat (but not really) answer your question, I was using Ember AJAX prior to using pretender and everything worked well.

Ember.$.ajax({
        type: "GET",
        url: ' https://api.myapp/1/users/restorepassword/SausageMuncher' ,
        processData: false,
        contentType: "application/json; charset=UTF-8",
        headers: {
          'application-id': 'xxx,
          'secret-key': 'xxx'
        }
      }).then(function() {
        Ember.run(function() {
          _this.set('infoMessage', 'Please check your email!');
          _this.set('errorMessage', '');
        });
      }, function(xhr) {
        Ember.run(function() {
          var messageObj = JSON.parse(xhr.responseText);
          _this.set('infoMessage', '');
          _this.set('errorMessage', messageObj.message);
        });
      });

I appreciate there is not much error handling in here.

If I get a chance to jump back onto this project in the up coming days, I'll write back to you here.

ArtOfSettling avatar Oct 11 '16 08:10 ArtOfSettling

I was using Ember AJAX prior to using pretender and everything worked well.

Subtle difference here; Ember.$.ajax is not Ember AJAX, it's just jQuery AJAX. If the code above works, then the issue must be somewhere in ember-ajax after all. I'll look into it again tonight.

alexlafroscia avatar Oct 11 '16 17:10 alexlafroscia

I didn't dive too far into this one, but I've pushed a failing test to my fork so there's something to muck with.

The exact error message I'm getting is "Unexpected end of JSON input" -- likely somewhere within jQuery there's an uncaught call to JSON.Parse on the empty string, which will produce that exact error.

Looking at @ArtOfSettling's code above, I'm thinking the reason raw Ember.$.ajax is working just fine is that the error handling function in the .then call (which is jqXHR's .then, not Ember's) is catching the parse error, whereas ember-ajax is letting it bubble up. From a quick scan of the code, I'm not seeing anything in ember-ajax's _makeRequest that handles outright failure of the ajax request (e.g. parse errors and whatnot). Perhaps there's a deeper discussion to be had here?

XaserAcheron avatar Dec 12 '16 20:12 XaserAcheron

I'm seeing this issue as well. API is responding with 202 no content but it's still trying to parse the response as JSON. Having to do this as a workaround:

this.get('ajax')
  .post(`https://api.example.com/foo/bar`, {
    contentType: 'application/json',
    data: JSON.stringify({ data })
  })
  .catch((e) => {
    if (e.message === "Unexpected end of JSON input") {
      return RSVP.resolve()
    } else {
      return RSVP.reject(e)
    }
  })
  .then(() => {
    // …
  })
  .catch((e) => {
    // …
  })

ezekg avatar Apr 18 '17 21:04 ezekg

@ezekg, I had the same problem and adding dataType: 'text' to post method fixed the error

thisFunction avatar Sep 25 '17 13:09 thisFunction

Thank you @thisFunction that solved it for me as well.

mukk85 avatar Dec 05 '17 10:12 mukk85

Nothing yet? I got this problem too

GitVitor avatar Apr 06 '18 00:04 GitVitor

Always up for reviewing a PR! I don't use ember-ajax regularly so I'll get to bug fixes as time allows.

alexlafroscia avatar Apr 06 '18 05:04 alexlafroscia