Handling errors with the RESTAdapter - ember.js

How to get the errors returned when calling a RESTAdapter method (by example deleteRecord).
I can see this code in the sources but I do not clearly understand.
Is there a sample code available providing error handling management with ember-model RESTAdapter ?
settings.error = function(jqXHR, textStatus, errorThrown) {
Ember.run(null, reject, jqXHR);
};

The Ember Documentation describes promises and how to handle them.

Related

How do I intercept ember-data response and take alternate action.?

I am using latest ember-data library for persistence in my Ember application.
Following is my route definition:
export default Ember.Route.extend({
model: function() {
return this.store.find('language');
}
});
There are two possible response for this:
Normal scenario: {"language":{"id":123,"name": "English"}}
Error scenario: {"error-response":{"status":"398648","message": "internal error."}} This is a standard error message for all errors.
In both the case, the response is returned with the "http 200 success" status code. So this means that the ember tries to call the resolve callback and generates error for error scenario. I need to handle this for our model definition. Is there any way I can intercept this response and take alternate action?
You could do this in a serializer, check it in there (http://emberjs.com/api/data/classes/DS.RESTSerializer.html#method_normalize) or something along the likes of:
export default Ember.Route.extend({
model: function() {
return this.store.find('language').then(function(language){
//perform your check on the response here
//if language contains error-response this.transitionTo('errorpage')
//else return language -- that kinda thing.
});
}
});
First of all, returning HTTP code 200 while getting an error is more than strange.
Ember expects reasonable response in error situation. It means, if you getting 4xx error, ember will activate Ember.Route.error hook (http://emberjs.com/guides/routing/loading-and-error-substates/#toc_code-error-code-substates); if server responded validation error (default code in Ember - 422), than Ember.Adapter will call extractValidationErrors and so on. In short, if you get an error, treat it as an error, and not as a successful response.

How to throw Ember.js errors?

In an ember.js application, how can we throw application errors (and have them bubble through the controller-route-application hierarchy?)
My use case is related to catching non ember-data ajax errors and handling them through the same path as ember data errors.
(i.e. when experiencing an error from a non-restful endpoint, allow that error to bubble through the application similar to ember-data errors)
If you want to throw errors, use throw new Error("Message");.
The user gets redirected to error route.
With Promises you can react on Exceptions, and handle them.
See: http://emberjs.com/api/classes/RSVP.Promise.html
Ember has its own EmberError class which sub classes the Javascript error class.
import EmberError from '#ember/error';
export default Route.extend({
/* Pseudo code... */
model() {
if(/* something bad happens */) {
throw new EmberError('Oh, no! Something bad happened!');
}
},
});
You can do something with it in an error action in your route. If you want it to bubble up, remember to return true.
actions: {
error(error) {
// do something
return true;
},
},
Ember automagically creates an error substate and a error template where you can display info about the error (without redirecting). You can show error info in application-error.hbs or error.hbs like so:
<h1>{{model.name}} {{model.status}}</h1>
{{model.stack}}
See the Ember substate guide for more options.

Rejection handler in latest ember-data (beta 1 and beta 2)

It looks like the latest versions of ember-data removed the rejectionHandler. Here is the old code https://github.com/emberjs/data/blob/4764b5d70c41c133edcbd1822bc587483c39e180/packages/ember-data/lib/adapters/rest_adapter.js#L11-L15 and example usage https://github.com/emberjs/data/blob/4764b5d70c41c133edcbd1822bc587483c39e180/packages/ember-data/lib/adapters/rest_adapter.js#L372.
I was using this to handle 401 unauthorized status codes from my server. Can I accomplish the same thing using the latest ember-data? I know I could pass a second function to all find and save calls to handle failure. But how to do that application wide?
To do that application-wide you should use the global error handling capabilities of the router.
App.ApplicationRoute = Ember.Route.extend({
actions: {
error: function(error, transition) {
//If error was a 401, do something...
}
}
});
See How to do cool stuff with the new Router API

How can I know the error reason in promise's rejection handler?

I wrote some code using find method like below.
The adapter is RESTAdapter.
App.SessionManager = Em.Object.extend({
userIdChanged: function() {
App.User.find(this.get('userid')).then(
function(user) {
/* process something */
},
function(error) {
/* rejection handler */
/* I want to know what error returned by the server here.*/
/* but how? */
}
);
}.observes('userid'),
});
If my server returned some error(e.g. 401) the rejection handler called.
But it seems that the argument of handler doesn't have error information.
How can I know the error reason in rejection handler?
Handling of errors returned by the server is not yet fully implemented in ember data.
For reference, as stated in this blog post about ember-data:
We want to make error handling and dealing with client and server conflicts rock solid. A pull request from Paul Chavard is currently open and looks like a solid starting point for error handling. You should see much more development on this in the near future.
But there are some workaround you can do to get to that information in the meanwhile.
For example:
Ember.RSVP.configure('onerror', function(error) {
console.log(error.message);
console.log(error.stack);
});
Or use a dirty hack to get to that information. Since ember-data uses jQuery under the hood you can subscribe to ajaxError:
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
// this will trigger anytime there is an error
});
Hope it helps.
you can also override this:
becameInvalid: function(record) {
// you can get errors just by doing record.errors, error keys must match
// the name of a field that you have defined in your model
}
and:
becameError: function(record) {
}
that's in case something happened in the server that caused an error. I just saw that you want to handle errors on promises, well, that's something different that I haven't dealt with. becameError might be fired.
UPDATE:
I just found something interesting that might help you: Ember-Data handling 401’s thanks to the new router, I haven't had the chance to use all those new features, but they look pretty cool.

Why is this property swallowing errors?

I have a property that depends on another property. There is an error in my code that happens when the other property is present. The error is being swallowed by something, probably Ember. This makes debugging the error very hard. I have tried setting Ember.onerror to a function that just logs the error, it makes no difference.
Why is Ember swallowing this error, how can I make it not?
Code:
App.DashboardController = Ember.Controller.extend({
leaderboard: function() {
console.log("calling leaderboard");
var ces = this.get("engagements");
if (ces) {
console.log("before");
throw new Error("bad thing");
console.log("after");
}
console.log("done")
}.property("engagements")
})
Console log:
calling leaderboard
done
(setting engagements)
calling leaderboard
before
Version: Ember.js RC6, development
Turns out the property "engagements" was being set inside a promise fulfilment handler. This article explains how to catch errors that occur in those: http://blog.sensible.io/2013/06/10/promise-ate-my-homework-exception.html