Ember ErrorRoute: model is null when throwing string - ember.js

I have an error route and controller defined in my Ember app and it generally works, but if some code throws a simple string, e.g. throw 'invalid argument', the model property on my error controller is always null.
I've created a JSBin example illustrating the problem.
Can anyone explain why throwing an object allows the model to be set but throwing a primitive like string does not? How can I capture the error context if I can't control the code that throws exceptions?
Additionally, it seems if I throw new Error('message') or throw new Ember.Error('message') the error is logged to the console but never triggers the error route transition. Is this intended?

Related

Ember Highcharts Component throwing odd error

I am trying to implement a dynamic highcharts that changes every time a new model comes in. In ember-highcharts documentation, they explain that all needs to be done is implement the EmberHighChartComponent and implement a contentdidchange observer that observes the model and would change the graph when the model changes
details here :
https://github.com/ahmadsoe/ember-highcharts#overriding-chart-redrawing
So when I implement it, it works perfectly and graph changes when there is new content, but as soon as I try to navigate somewhere else on the page, it throws this error:
Even when I emptied the component this happens, which tells me that the problem is in EmberHighChartComponent
this is what I have after emptying the component
dynamic-chart.js
import EmberHighChartsComponent from 'ember-highcharts/components/high-charts';
export default EmberHighChartsComponent.extend( {
});
dynamic-chart.hbs
{{high-charts mode=mode chartOptions=chartOptions content=content}}
The Error that I get:
TypeError: undefined is not an object (evaluating 'chart.renderTo.removeAttribute')
Any ideas whether this is a package issue or I am misunderstanding the implementation ?
Remove dynamic-chart.hbs file. You extending a component, not wrapping it.

Ember JS queryRecord not triggering error state when record not found

I have a model hook on a route that ends by returning a Promise like:
return route.store.queryRecord(model, {username: params.username});
This works great except it doesn't trigger the "error" action that is anywhere in the chain. It is getting a 404 and logging the error in the console.
If I change the call to "find" with a id that doesn't exist it throws the same 404, but calls the transition to the error state. I cannot use the find for several reasons. Am I missing something simple?
Using ember 2.4.
Looks like queryRecord does not catch errors that are raised in the promise as we can see here: https://github.com/emberjs/data/blob/v2.5.3/addon/-private/system/store/finders.js#L194
What you can do in this case is to encapsulate the call to store.query in a Promise that you would return in your routes model hook, analyze the result of store.query and reject the encapsulating Promise if you get a 404.

How to trigger `error` action *outside* of a transition

I'm looking to implement some consistent error handling in my app through the error action. The problem I've run into is that it is only triggered when an exception is raised while in a transition, and not, for example, in a plain saveModelInResponseToUserClick action on a route.
I can sort of get something to work with the following, but it's a hack:
Ember.onerror = function(error) {
MyApp.__container__.lookup('router:main').send('handleError')
}
With that, I could have different error-handling logic in differently-nested routes.
EDIT: Another issue with using the method above is when an error occurs before the app has fully transitioned into its first route - another exception is raised in that case and everything blows up.
Is there a different approach I can take with this?
As you said, the error action will only trigger while in transition.
For errors that may arise from an action, you could try using the following:
Ember.RSVP.on('error', function(error) {
// handle error
}
This will catch ANY error that occurs as a result of a promise in your app. You can access the "error" object inside the function, which will give you some detail as to what exactly went wrong, particularly the "responseText" attribute. The code itself goes in your app.js file.
Ember docs on this: http://emberjs.com/guides/understanding-ember/debugging/#toc_errors-within-an-code-rsvp-promise-code

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

Throw error in error function of $http causes $digest already in progress in unit test

Here is a plunker showing the issue:
http://plnkr.co/edit/J8zRIj?p=preview
Here is a plunker with the error commented out in both the scripts.js and scripts.spec.js and I don't get the $digest error anymore:
http://plnkr.co/edit/jCRlwf?p=preview
Throwing and testing for errors seems to work when they are not inside a callback of an $http request. Anyone know why this might not be working?
The problem is that the mock $exceptionHandler service re-throws exceptions by default. So your exception is causing a $rootScope.$apply to be aborted in the middle.
One solution is to switch the mock $exceptionHandlerProvider to 'log' mode and then check $exceptionHandler.errors. See here.