开发者

How backbonejs models handle server side errors?

开发者 https://www.devze.com 2023-03-07 17:58 出处:网络
How backbonejs models handle server side errors? When 开发者_Go百科Im sending json with errors array, im still get a success callback with errors array inside response parameter.In my client-side cod

How backbonejs models handle server side errors?

When 开发者_Go百科Im sending json with errors array, im still get a success callback with errors array inside response parameter.


In my client-side code I check for the presence of the errors attribute and react as necessary.

For example, I was using the Collection.create function, which calls the add function of the Collection if the request was successful. So, I overrode my Collection's add function to prevent the model from being added if it has an 'errors' attribute, and if it doesn't call the "super" method.

add: function(object, options) {
    if (_.isArray(object) || !object.get('errors')) {
        Backbone.Collection.prototype.add.call(this, object, options)
    }
},

Having my app return a non-success status code would work too, as it prevents success callbacks from being run. But, I didn't like the idea of returning a 400 error just because the submission was invalid. That's something I've never had to do in non-Backbone.js apps. ("Invertebrates"?)

None of the descriptions for 4XX status codes seemed to really match the concept of failed validation. 400 and 403 come close, but still come off as if they were intended for other uses. On the other hand, the user really doesn't care what status code you return; might as well be a 404.

It's really a matter of whether you want to write more code server-side or client-side. My application more or less ignores the outcome of validation and returns the record serialized to JSON whether it was saved or not, so I chose to work from that angle.


Server side backbone validation:

Server side

Return errors array

Client side

Pass "wait: true" as option when calling model.save:

modelVar.save(data,{ // here be options
    wait: true,
    success: this.processRequest,
    error: this.processErrors
});

Update the model's validate function to check for the errors array:

validate: function(attrs) {
    this.errors = [];
    if (attrs.errors && attrs.errors.length > 0) {
        for (var key in attrs.errors) {
            this.errors.push(attrs.errors[key].errorMessage);
        }
    }
    return _.any(this.errors) ? this.errors : null;
}

Outcome

The error callback will run and the model will not "change" if the server retruns [errors].

UPDATE:

As of version 0.9.10 this will no longer work. You should either use the "invalid" event or use the new options argument of the model.validate(attributes, options) function: if (typeof(options.error === 'function')) options.error();


Or may be I should use http status. Currently I have chosen 403 status to indicate validation errors on server side. More info about statuses could be found here: http://restpatterns.org/HTTP_Status_Codes


Backbone.js routes its ajax calls through whatever underlying library you have in place; JQuery or Zepto. So basically, this library decides what constitutes success and what constitutes error.

It sounds like your server may be returning a 403 status code, but that is being interpreted as a success return. Thus, your success callback is being called. For what its worth, a 403 status code seems odd for returning errors unless these errors are authorization-related.

Is this what you were looking for?


I'll speak to using jQuery as your underlying js library (though I assume zepto works the same way). Backbone routes async events like model.save() collection.fetch(), etc...through Backbone.sync(). This function delegates to $.ajax() to do the actual ajax call. So whatever error function you've specified when you created you object will be used AS LONG AS the header of the response signifies an error, like a 4XX header.

Often you will see error handling done in the success function, because the return does not actually signify an error to jquery (when the response header is 2XX).


I normally return an HTTP Error from the server along with a JSON Error description, something like this:

var xhr = myModel.save();
// On error show an alert
xhr.fail(function () {
  try {
    // Assuming you are returning json error response like ["Error desc 01","Error desc 02"]
    errors = JSON.parse(xhr.responseText);
    alert(errors.join("\n"));
  } catch(e) {
    // Unknown error cause
    alert("The server failed to respond, please try again later.");
  }
});
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号