2
votes

When I request a single resource that returns a 404 (or 403 for that matter) Ember Data is creating a local record.

For example, I load my app from scratch at /items/123. The adapter does a request for GET /items/123 which results in a 404 but now I have an item record in my local store with id=123. All attributes are undefined expect where the model defines default values.

Also, all model flags are false except isValid which is true.

Is this excepted behaviour? It seems strange that the local record gets created even though the server is saying that it doesn't exist (or that the user is not allowed to see it).

Details

I'm running Ember 1.8.1 and Ember Data 1.0.0-beta.11.

Here's what I have for Routes—pretty basic stuff:

// itemsRoute, TOP LEVEL
model: function() {
  return this.store.find('item');
}


// itemRoute, CHILD LEVEL
model: function(params) {
  return this.store.find('item', params.item_id); // <-- this returns 404
},
actions: {
    error: function(err) {
      this.replaceWith('items'); // jump out to main list view
      return true; // ensure error bubbles up
    }
}

The rejection in the model hook is working because the error action is triggered and I'm redirected out the top level /items view. But I still end up with a local record for an item that doesn't exist.

2
I haven't seen this happen. Are you sure the server is actually returning 404? Asking on the off chance that it's responding with some sort of custom "404" implementation but actually returning 200 in the header. If not, can you provide some code example to help better understand the behavior? - user239546
Server is returning a proper 404 code (screenshot: cl.ly/Yq8W). I've added some code snippets from my Routes...it's pretty basic stuff I think. - Eli Dupuis
It seems a little weird to me. I'm wondering it replaceWith() is behaving differently than we're assuming it does. I haven't been able to replicate this the phantom null record due to a failure, but if nothing else works you could consider overriding the ajaxSuccess and/or ajaxError method for the adapter. - user239546
Strange indeed. I have been able to catch the error in ajaxError in the adapter but I haven't followed through on that approach yet. - Eli Dupuis
This is a little uglier. You could also override the afterModel [aftermodel(model, transition)] method and do a reload on the model in the instance that the transition reveals a 404. It's not very elegant though. Hrm... is there a reason the server is returning a 404 error as opposed to an empty data set or JSON response with error property? - user239546

2 Answers

0
votes

After thinking about this a little more... try altering your error handler in itemRoute from...

actions: {
    error: function(err) {
      this.replaceWith('items'); // jump out to main list view
      return true; // ensure error bubbles up
    }
}

to...

actions: {
    error: function(err) {
        this.transitionTo('items');  // jump out to main list view
        return false;  // Stop event bubbling - we've handled it.
        //You could also console.log parts or all of your error

        //You can return true too if you want to keep the event bubbling.
    }
}

I don't have a concrete reason for why this would be yet. Waiting to hear back from you if it worked.

0
votes

This is most definitely a bug. It seems this was fixed a while back but as was reintroduced by a change on March 14.

I've submitted a bug report https://github.com/emberjs/data/issues/3085