API Proposal: Errors on embedded records


#1

Sth. that’s currently missing in ember-data is correct handling of errors on embedded records. Any errors from responses are only read from the top level and only assigned to the “top level” record, e.g. a request like this

POST /people
{ person: { name: '', group: { name: '' } } }

with this response:

{ errors: {
  name: ['cannot be empty'],
  group { name: ['cannot be empty'] }
}}

will only invalidate the person record any only assign the “cannot be empty” error to that record - the errors of the embedded group are ignored.

Of course there’s a bigger discussion currently going on regarding error handling in general (see e.g. https://github.com/json-api/json-api/issues/7) and I also think it’s apparent that simply returning plain error messages can’t really be the final solution. As it’s unlikely though that there will be an agreement any time soon (probably not before ember.js/ember-data 1.0 are final), I’d rather fix the problem of errors on embedded records now and potentially at a later point change the error handling mechanism again.

My proposal would be to process errors on embedded records like in the above response and assign the errors to the embedded records/ invalidate the records accordingly.

Of course there are more cases, e.g. deeply nested embedded records:

POST /people
{ person: { name: '', group: { name: '', category: { name: '' } } } }

with error response:

{ errors: {
  name: ['cannot be empty'],
  group: {
    name: ['cannot be empty']
    category: { name: ['cannot be empty'] }
  }
}}

or one-to-many relationships where only some of the embedded records might have errors:

POST /articles
{ article: { title: 'some article', tags: [
  { tag: { title: '' } }, { tag: { title: 'ember.js' } }, { tag: { title: '' } }
] } }

with response:

{ errors: {
  tags: [
    { title: ['cannot be empty'] },
    {}, //no error on the 2nd tag
    { title: ['cannot be empty'] },
  ]
}}

I also opened a pull request on the topic (that only contains parts of what would be necessary though: https://github.com/emberjs/data/pull/1058).

Would love to get some feedback!


#2

I too have this same problem (although this has been the only reference anywhere I’ve seen to the problem - good to know it’s not just me). Your PR was closed because at the time there was no embedded record support provided by ED, but now that there is, this seems to be a glaring hole IMO.

I’ve sort of accomplished this by over-riding the extractErrors method of the serializer and some other very hacky things and then calling recordWasInvalid on each embedded record. However, this is still in active development and I don’t know yet if I’ve broken things by doing this.

So…long story short…now that ember supports, at least in part, embedded records, how are we supposed to deal with embedded errors?

If it helps, here’s my use-case: The API I’m dealing with uses embedded JSON to sort of mimic a transactional boundary so when you save something like an order, you send the order header, all the lines (new or updated) and the attached customer object (new or updated). Some of these are stand-alone entities in their own right (like customer). Anyways, if something doesn’t validate then it rolls the whole thing back and send you the entire payload back with errors embedded in the JSON at the level in which they happened.