How should I handle errors when using Ember.js Data RESTAdapter?

ember-data.js: https://github.com/emberjs/data/tree/0396411e39df96c8506de3182c81414c1d0eb981

In short, when there is an error, I want to display error messages in the view, and then the user can: 1) cancel, roll back the transaction 2) correct the input errors and successfully complete the transaction, passing checks on the server.

Below is a snippet of code from the source. It does not include an error callback.

updateRecord: function(store, type, record) { var id = get(record, 'id'); var root = this.rootForType(type); var data = {}; data[root] = this.toJSON(record); this.ajax(this.buildURL(root, id), "PUT", { data: data, context: this, success: function(json) { this.didUpdateRecord(store, type, record, json); } }); }, 

In general, what is the flow of receiving errors from the server and updating the view? It seems that the error callback should put the model into an isError state, and then the view can display the corresponding messages. In addition, the transaction must remain dirty. Thus, a transaction can use rollback .

Using store.recordWasInvalid seems to be going in the right direction.

+42
ember-data
Oct 19
source share
4 answers

This weekend I tried to understand the same thing. Based on what Luke said, I took a closer look at the ember-data data source for the last commit (December 11th).

TL; DR; to handle ember-data / create errors, just define becameError() and becameInvalid(errors) on your DS.Model instance. The cascade caused by the AJAX RESTadapter error callback will eventually call these functions that you define.

Example:

 App.Post = DS.Model.extend title: DS.attr "string" body: DS.attr "string" becameError: -> # handle error case here alert 'there was an error!' becameInvalid: (errors) -> # record was invalid alert "Record was invalid because: #{errors}" 

Here's a full walk on the source:

In the REST adapter, the AJAX callback function is provided here :

  this.ajax(this.buildURL(root, id), "PUT", { data: data, context: this, success: function(json) { Ember.run(this, function(){ this.didUpdateRecord(store, type, record, json); }); }, error: function(xhr) { this.didError(store, type, record, xhr); } }); 

didError is defined here , and it in turn raises a storeWasInvalid or recordWasError entry depending on the response:

  didError: function(store, type, record, xhr) { if (xhr.status === 422) { var data = JSON.parse(xhr.responseText); store.recordWasInvalid(record, data['errors']); } else { store.recordWasError(record); } }, 

In turn, store.recordWasInvalid and store.recordWasError (defined here ) call write handlers (DS.Model). In the invalid case, it passes error messages from the adapter as an argument.

  recordWasInvalid: function(record, errors) { record.adapterDidInvalidate(errors); }, recordWasError: function(record) { record.adapterDidError(); }, 

DS.Model.adapterDidInvalidate and adapterDidError (defined here ) are just send('becameInvalid', errors) or send('becameError') , which ultimately leads us to the handlers here :

  didLoad: Ember.K, didUpdate: Ember.K, didCreate: Ember.K, didDelete: Ember.K, becameInvalid: Ember.K, becameError: Ember.K, 

(Ember.K is just a dummy function to return this . See here )

So, the conclusion is that you just need to define functions for becameInvalid and becameError for your model to handle these cases.

Hope this helps someone else; documents, of course, do not reflect this right now.

+42
Dec 12 '12 at 17:30
source share
β€” -

DS.RESTAdapter just got a bit more error handling in this commit , but we're still not at the point where we have a great recommendation for error handling.

If you are ambitious / crazy enough to put applications into production today using ember data (like me!), It is best to make sure that the probability of crashes in your API is extremely low. those. Verify your client side of the data.

Hope we can update this question with a much better answer in the coming months.

+8
Nov 23 '12 at 5:10
source share

I just ran into this situation, not sure if this has already been explained anywhere.

I use:

 Em.VERSION : 1.0.0 DS.VERSION : "1.0.0-beta.6" Ember Validations (dockyard) : Version: 1.0.0.beta.1 Ember I18n 

At first, the model was mixed with validation.

 App.Order = DS.Model.extend(Ember.Validations.Mixin, { ..... someAttribute : DS.attr('string'), /* Client side input validation with ember-validations */ validations : { someAttribute : { presence : { message : Ember.I18n.t('translations.someAttributeInputError') } } } }); 

The appropriate steering wheels are added to the template. (note that ember checks will automatically add errors to model.errors.<attribute> in case of input validation, I will also use the same compromise in server validation)

 <p>{{t 'translations.myString'}}<br> {{view Ember.TextField valueBinding="attributeName"}} {{#if model.errors.attributeName.length}}<small class="error">{{model.errors.attributeName}}</small>{{/if}} </p 

Now we will save Order

 App.get('order').save().then(function () { //move to next state? }, function(xhr){ var errors = xhr.responseJSON.errors; for(var error in errors){ //this loop is for I18n errors[error] = Ember.I18n.t(errors[error]); } controller.get('model').set('errors', errors); //this will overwrite current errors if any }); 

Now, if there is a validation error output from the server, the returned packet is used

 {"errors":{"attributeName1":"translations.attributeNameEror", "another":"translations.anotherError"}} status : 422 

It is important to use status 422

This way your attributes can be checked on the client side and again on the server side.

Disclaimer: I'm not sure if this is the best way!

+3
Feb 27 '14 at 10:27
source share

Since there is currently no good solution in the Ember-Data warehouse, I made my own decision by adding the apiErrors property in DS.Model and then into my RestAdapter subclass (I already needed my own). I added error callbacks to Ajax that calls createRecord and updateRecord , which save the errors and put the model in an β€œinvalid” state, which means that the client or server side validation failed.

Here are the code snippets:

This could be in the application.js file or another top-level file:

 DS.Model.reopen({ // Added for better error handling on create/update apiErrors: null }); 

This applies to error callbacks for createRecord and updateRecord in the RestAdapter subclass:

 error: function(xhr, textStatus, err) { console.log(xhr.responseText); errors = null; try { errors = JSON.parse(xhr.responseText).errors; } catch(e){} //ignore parse error if(errors) { record.set('apiErrors',errors); } record.send('becameInvalid'); } 
+2
Dec 04
source share



All Articles