What happens when ember's model hook's request fails


#1

I have a typical scenario. My model hook for Route-1 looks something like this.

model() {
  return Ember.RSVP.hash({
    posts: this.store.findAll('post'),
    authors: this.store.findAll('author')
  });
 }

If I’m on Route-2 and navigate to Route-1 it will call the model hook. And if I already have data on my store, both the findAll requests are resolved, triggering RSVP.hash to resolve.

But if the request fails, I’m getting undefined error in my console (chrome).(twice for each of findAll) My error tracking system reports it as Unhandled promise error detected

the stack shows no relevant info either

defaultDispatch @ ember.debug.js:18008  
dispatchError @ ember.debug.js:17987  
onerrorDefault @ ember.debug.js:31634  
trigger @ ember.debug.js:58713  
(anonymous) @ ember.debug.js:59614  
invokeWithOnError @ ember.debug.js:346  
flush @ ember.debug.js:405  
flush @ ember.debug.js:529  
end @ ember.debug.js:599  
(anonymous) @ ember.debug.js:1165  

There is not much help from the stack trace. My adapter hooks returns successfully. And then there is error in my console. I am not able to figure out what is causing the error to be thrown because the promise findAll already got resolved. And ember tells me I have not handled the promise!

I tried putting catch/reject codes everywher but it never gets called. Because of course the promise was already resolved. So, it can not be rejected.

Then where is this error coming from!! I have no clue. The only thing I could find was, my serializer does not get called when the error arises. So, probably the error is thrown before ember-data calls normalizeFindAllResponse.

The only thing I could find was in my serializer normalizeFindAllResponse was not invoked whenever such failures happened.

Any help is greatly appreciated. Thanks!


#2

See the docs for Store#findAll to see the options you can pass for various types of loading behaviour


#3

I know the loading behaviors. I’m wondering where is the error coming from. Is it the store or somewhere else?


#4

Due to the options / configuration, it’s most likely the background reloading that’s failling if the transition is sucessful


#5

I have not specified background reloading or should reload options.
Only a simple fetch this.store.findAll('post').

And transition is successful as the data is already available in the store.


#6

The symptoms you describe sound very much like background reloading is happening. It doesn’t only matter what options you specify in the findAll call, it matters what you configure in your adapter and the defaults there too.


#7

I have not set background reloading in my adapter either. Unfortunately I did not notice this before but this happens when other type of my requests fail too (like create, updateRecord etc). So it is not the problem with find all.


#8

Also, this is happening when I reject the promise in adapter. I’m beginning to wonder if I have to reject promise in a particular pattern or so.


#9

If you have changed your adapter code, it sounds like there is a problem there in that case


#10

I somehow solved the issue.

Before I was rejecting the promise with response reason object. Now, in case of error response, I am rather sending an object containing errors array, rather then failure reason object. So, the object will get passed as payload to my normalizeFindAllResponse in serializer. There I check for existance of errors array in our payload parameter. If there is such object then just return an empty object with data attribute set to empty array.

Got the idea from here.

Thanks @alexspeller