1
votes

I have an ember app with a rails backend.

I have a specific error that Rails can return (401) that I would like Ember to catch and act upon. In that case I would like to perform a custom method (which essentially modifies the request cookie) and then makes the request again.

Right now I am catching this error at the top level router and forcing the entire app the reload with window.location.reload(). Obviously this is a terrible hack. I was not able to get router.refresh() to work, but that would still be a hack anyway.

Ideally I would catch this much closer to the adapter so I can act on it. Perhaps I could catch this instead at the adapter level by overriding handleResponse(), but how would I retry the request from there?

http://emberjs.com/api/data/classes/DS.RESTAdapter.html#method_handleResponse handleResponse does pass along the requestData, but I would need some way to perform the request in the context of the adapter's methods, right?

2
I guess your server returns 401 when user is not athorized to make a request, am I right? If so, please tell how do you handle authorization: do you use ember-simple-auth or something else?Gennady Dogaev
I have rolled my own auth solution. I store some user metadata in local storage. In addition Rails maintains a session. This problem comes up when the rails session has expired and local storage has not. This design is definitely not the best solution (I think I am going to remove the local storage part eventually), but thats how it works now.Jono

2 Answers

0
votes

Well, you can handle this error in application route (what I did):

error: function (error, transition) {
 /**
  * Code below may vary depending on your server's response format
  */
  if (error.errors !== undefined) {
    for (var i = 0; i < error.errors.length; i++) {
      if (error.errors[i].status !== undefined) {
        if (parseInt(error.errors[i].status) === 401) {
          transition.abort(); //this line may not be needed in last versions, I'm not sure
          //Do what should be done, redirect to authentication for example
          //transition.retry(); should work too
          break;
        }
      }
    }
  }
}

It may look like "too high level", but it's how you handle errors in ember. Some time ago I wrote a post about error handling, you may take a look if you are interested. Of course you may want to extend an adapter to handle errors, but I would not suggest doing so. First, you will not have an access to route/controller inside adapter's methods. Second, it is not an "ember way". Adapter should return a promice, which will be rejected in case of error and it should not handle errors in any other way.

0
votes

If route's model hook get's rejected it calls out error method

You could make a mixin and wrap it to your routes.

import RouteMixin from 'xx/mixins/route';

Ember.Route.extend(RouteMixin, {

})

And inside the RouteMixin add an action

error: function() {          
   // this.transitionTo('/not-found');
}

Arguments of error.

  • Sever response
  • Transition class
  • Route related info

You could change request params and make re-route.