Ember.js: How to track down deferred action runtime errors? - javascript

I occasionally get the following runtime error.
Assertion failed: Error while loading route: TypeError: Cannot call method 'get' of undefined ember.js?body=1:3226
(anonymous function) ember.js?body=1:3226
defaultActionHandlers.error ember.js?body=1:32032
triggerEvent ember.js?body=1:31884
trigger ember.js?body=1:30910
Transition.trigger ember.js?body=1:30131
handleError ember.js?body=1:31244
invokeCallback ember.js?body=1:8377
(anonymous function) ember.js?body=1:8431
EventTarget.trigger ember.js?body=1:8200
(anonymous function) ember.js?body=1:8502
DeferredActionQueues.flush ember.js?body=1:5674
Backburner.end ember.js?body=1:5765
Backburner.run ember.js?body=1:5804
executeTimers ember.js?body=1:6056
(anonymous function) ember.js?body=1:5914
The problem is that the entire call stack is ember code. But the error must be caused by my code.
What is a generic approach to determine the original code that is causing the problem?

Set your debugger to stop on all exceptions, then walk up the stack trace and find out what code of yours is firing it.
This particular error looks like you were transitioning to another route and it blew up. There are only a few things (major understatement) that happen during the transition, I'll point out the biggins that would break the transition, they are all located on the route.
overridden model hook
overridden setupController hook
overridden serialize hook
You'll want to look through your code and add either add some validation that an item exists before you call get on it, or switch to using Ember.get(obj, property), but that just pushes off your exception until later.
I see this error a lot in the setupController and serialize hook.
serialize: function(model){
// good spot to fail
return { custom_id: model.get('some_id') };
}
setupController: function(controller, model){
// good spot to fail
var something = model.get('something');
}
These particular areas speak to a bigger issue, your model hook (or transitionTo/transitionToRoute code) is passing a null/empty model.

Related

Why is "this" undefined when hooking abstract methods using Frida?

it's two days that I am having a problem hooking and calling getPackageInfo using Frida.
I have wrote this code:
Java.perform(()=>{
const jPM=Java.use('android.app.ApplicationPackageManager');
const getPkgInfo=jPM.getPackageInfo.overload('java.lang.String','int');
getPkgInfo.implementation=(pname,f)=>{
console.log("Called => getPackageInfo (Flag="+f+", Pkg="+pname+")");
return getPkgInfo(this,pname,f);
}
});
At the line that calls getPkgInfo (return getPkgInfo(this,pname,f);) i get this error:
Called => getPackageInfo (Flag=0, Pkg=test.app)
{"type":"error","description":"TypeError: cannot read property '$getHandle' of undefined","stack":"TypeError: cannot read property '$getHandle' of undefined
at value (frida/node_modules/frida-java-bridge/lib/class-factory.js:1052)
at e (frida/node_modules/frida-java-bridge/lib/class-factory.js:585)
at <anonymous> (/script.js:42)
at apply (native)
at ne (frida/node_modules/frida-java-bridge/lib/class-factory.js:619)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/class-factory.js:597)","fileName":"frida/node_modules/frida-java-bridge/lib/class-factory.js","lineNumber":1052,"columnNumber":1}
So the method is hooked, because i can see the Called => getPackageInfo (Flag=0, Pkg=test.app) string, but i can't call the original method.
This happens only when i try hooking methods that are normally called using the abstract variant (in this case android.content.pm.PackageManager.getPackageInfo, but i have also tried hooking getPackageManager).
I have made different versions of this code, for example one that calls the function in this way: this.getPackageInfo.overload('java.lang.String','int').call(this,pname,f); and i get an error saying that "this" is undefined, so i think that it is the problem.
I have tried this script on different apps and devices but i always get the same result.
I am using Frida Inject.
Please help me.

Why is this findOne in a template event causing a call stack size error?

I am trying to have a forEach in SpaceBars that shows some buttons that can be pressed for each thing in an array. However, when I press the button, it gives me this error:
Uncaught RangeError: Maximum call stack size exceeded underscore.js:1025
_.(anonymous function) # underscore.js:1025
EJSON.clone # ejson.js:475
(anonymous function) # ejson.js:494
.each..forEach # underscore.js:113
EJSON.clone # ejson.js:493
... same stuff for a while ...
.each..forEach # underscore.js:113
EJSON.clone # ejson.js:493
(anonymous function) # ejson.js:494
.each..forEach # underscore.js:113
EJSON.clone # ejson.js:493
This is the findOne that's causing the error:
"click .acceptFriend": function(requester){
currentUserId = Meteor.userId();
requesterUsername = requester;
requesterId = friendRequests.findOne({$and:[{target:currentUserId}, {requester:requesterUsername}]})._id;
Meteor.call("acceptRequest", requesterId, requester);
}
I know it's the friendRequests.findOne because I have done console logs on each line, and that is the line that breaks it. I have tried several different variations, but it seems that any type of find on the friendRequests collection in that context breaks it. The relevant part of the template is this:
{{#each getRequests}}
{{requester}} <button class='acceptFriend'>accept</button>
{{/each}}
Why is this error happening and how can I solve it?
If we look at the documentation about events:
The handler function receives two arguments: event, an object with
information about the event, and template, a template instance for the
template where the handler is defined. The handler also receives some
additional context data in this, depending on the context of the
current element handling the event. In a template, an element's
context is the data context where that element occurs, which is set by
block helpers such as #with and #each.
To sum up: events in Meteor do not receive their data context as an argument: they receive the event object and the template instance where the event occured. The data context is stored in this.
So what you should probably do is the following:
"click .acceptFriend": function(event, template){
currentUserId = Meteor.userId();
requesterUsername = this.requester;
requesterId = friendRequests.findOne({$and:[{target:currentUserId}, {requester:requesterUsername}]})._id;
Meteor.call("acceptRequest", requesterId, requesterUsername);
}

Error with Ext.Msg in js-test-driver tests

In my js-test-driver tests, I'm having an error from simply calling
Ext.Msg.alert('Error', 'An error occurred while trying load parameters for action with id ' + actionId);
Error Message: Uncaught TypeError: Cannot read property 'insertBefore' of null
Note that Ext.Msg.rendered is true and that Ext.Msg.el.dom.parentNode is null if I stop execution just before the error.
This error does not happen if:
The real app is running, only during tests.
If I run a single test, only if I run multiple tests that end up calling Ext.Msg.alert
Stack trace
Ext.define.insertBefore (ext-all-debug.js:13281)
Ext.define.show (ext-all-debug.js:42064)
Ext.define.sync (ext-all-debug.js:82755)
Ext.define.syncShadow (ext-all-debug.js:33992)
Ext.define.onAfterFloatLayout (ext-all-debug.js:34002)
Ext.define.afterComponentLayout (ext-all-debug.js:34374)
Base.implement.callParent (ext-all-debug.js:4455)
Ext.define.afterComponentLayout (ext-all-debug.js:38639)
Ext.define.notifyOwner (ext-all-debug.js:38067)
Ext.define.callLayout (ext-all-debug.js:125114)
Ext.define.flushLayouts (ext-all-debug.js:125283)
Ext.define.runComplete (ext-all-debug.js:125769)
callOverrideParent (ext-all-debug.js:36)
Base.implement.callParent (ext-all-debug.js:4455)
Ext.override.runComplete (ext-all-debug.js:29905)
Ext.define.run (ext-all-debug.js:125750)
Ext.define.statics.flushLayouts (ext-all-debug.js:29913)
Ext.define.statics.updateLayout (ext-all-debug.js:29947)
Ext.define.updateLayout (ext-all-debug.js:31844)
Ext.define.onContentChange (ext-all-debug.js:36116)
Ext.define.updateLayout (ext-all-debug.js:31839)
Ext.define.onContentChange (ext-all-debug.js:36116)
Ext.define.updateLayout (ext-all-debug.js:31839)
Ext.define.setTitle (ext-all-debug.js:53058)
Ext.define.setTitle (ext-all-debug.js:55155)
Ext.define.reconfigure (ext-all-debug.js:90310)
Ext.define.show (ext-all-debug.js:90476)
Ext.define.alert (ext-all-debug.js:90600)
Ext.define.onInstanceRetrievalError (BaseWorkflowActionController.js:139)
(anonymous function) (ext-all-debug.js:2265)
Ext.apply.callback (ext-all-debug.js:7437)
Ext.define.Ext.apply.inheritableStatics.load (mock.js:38)
Ext.define.onDocumentClick (BaseWorkflowActionController.js:73)
(anonymous function) (VM6566:6)
Ext.apply.createListenerWrap.wrap (ext-all-debug.js:10786)
AsyncTestCase.test_unknown_error_displays_error_dialog (WorkflowSingleActionController.Test.js:87)
Any ideas of what could be going on? Or something to try?
This question was cross-posted to http://www.sencha.com/forum/showthread.php?288372-Error-calling-Ext.Msg.alert-from-js-test-driver-tests&p=1053744#post1053744
The problem is that js-test-driver runs the following code which removes any content from the DOM at the end of each test.
var testRunnerPlugin =
new jstestdriver.plugins.TestRunnerPlugin(Date, function() {
jstestdriver.log(jstestdriver.jQuery('body')[0].innerHTML);
jstestdriver.jQuery('body').children().remove();
jstestdriver.jQuery(document).unbind();
jstestdriver.jQuery(document).die();
}, runTestLoop);
Therefore, the global Ext.Msg which was rendered onto the body becomes orphaned and it fails when trying to sync the shadow.
The solution is not to use the global Ext.Msg, always instantiate a new Ext.message.MessageBox if you want your code to be testable in js-test-driver
Here's a test case that reproduces the exact same stack trace https://fiddle.sencha.com/#fiddle/7i1

Object has no method 'call' when setting Backbone Model from Trigger

So, I just spent about 3 hours trying to debug this nasty thing and I'm at wits end.
What I'm trying to do is fairly simple. I'm working with a search query (string) and trying to set a global model with its attributes. However, when I'm moving to a different view, I want the model to clear out these attributes, or of course when they enter a new search query, have the event fire again. I'm trying to use the Backbone Marionette Wreqr / Event Aggregator to manage the events here.
I don't know if it's because I'm using requirejs, or not scoping things correctly, but I'm hitting this very confusing error:
Uncaught TypeError: Object #<Object> has no method 'call' backbone.amd.min.js:1
f backbone.amd.min.js:1
e.Events.trigger backbone.amd.min.js:1
i.extend.set backbone.amd.min.js:1
(anonymous function) app.js:42
f backbone.amd.min.js:1
e.Events.trigger backbone.amd.min.js:1
Application.searchRoute app.js:81
(anonymous function) backbone.amd.min.js:1
(anonymous function) backbone.amd.min.js:1
w.some.w.any underscore.amd.min.js:1
i.extend.loadUrl backbone.amd.min.js:1
i.extend.navigate backbone.amd.min.js:1
i.extend.navigate backbone.amd.min.js:1
SidebarLayout.search sidebar.js:177
(anonymous function) sidebar.js:3
x.event.dispatch jquery.min.js:5
y.handle
And here's some of my application code (my main controller). As you can see, I'm trying to set up the app.searchResult model with these other parameters from the searchRoute method.
What's so bizarre is that it works the first time the page loads, but when I attempt to use router navigate or do anything but refresh the page, it fails.
I tried using #searchResult instead, tried adding a , # after my trigger call, and all sorts of other things. What's stranger is that inside that scope, app.searchResult is available to me. And as soon as I remove the set call from there, the error doesn't happen anymore, so I'm thinking it must be that?
define [
'backbone.marionette',
'global/layouts/home',
'global/layouts/layout',
'search/models/search-results',
'search/collections/panels',
'global/collections/categories',
'global/collections/stores',
'global/collections/searchResults',
'search/views/panels',
'apps/router'
], (Marionette, homeLayout, subpageLayout, SearchResultModel, PanelsCollection, CategoriesCollection, StoresCollection, SearchResultsCollection, PanelsView, Router) ->
class Application extends Backbone.Marionette.Application
onInitializeAfter: =>
# Main Region
#addRegions
mainRegion: '#app'
# AppRouter
#router = new Router controller: #
# Request Response / Vent
#reqRes()
#appVent()
# Global Search Result Model
#searchResult = new SearchResultModel()
Backbone.history.start
pushState: false
root: ""
searchRoute: (query, params) ->
params = $.extend params, text: query
#vent.trigger "search:setParams", params
#subpageLayout = new subpageLayout()
#mainRegion.show #subpageLayout
appVent: ->
#vent.on "search:setParams", (params) ->
app.searchResult.set("params", params)
#vent.on "sidebar:reset", ->
app.searchResult.set("params", null)
I can send more code if you like, but the idea is to use a custom trigger like sidebar:reset to clear out these parameters. I'm also listening to some model events (all of that stuff is working great from within the context of the view and when I don't mess with the event aggregator).
Thanks in advance for your help. You have no idea how many hours I just spent on this!

Ember.js - Cannot perform operations on a Metamorph that is not in the DOM

I am using Ember.js version 1.0.0-rc.3 and recently started seeing:
Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM. lib- dev.js:28254
Metamorph.checkRemoved lib-dev.js:28254
Metamorph.html lib-dev.js:28224
SimpleHandlebarsView.update lib-dev.js:29167
(anonymous function) lib-dev.js:14424
Ember.handleErrors lib-dev.js:10331
invoke lib-dev.js:14422
invokeOnceTimer lib-dev.js:14875
(anonymous function) lib-dev.js:14424
Ember.handleErrors lib-dev.js:10331
invoke lib-dev.js:14422
iter lib-dev.js:14492
RunLoop.flush lib-dev.js:14546
RunLoop.end lib-dev.js:14451
tryable lib-dev.js:14652
Ember.tryFinally lib-dev.js:11119
Ember.run.end lib-dev.js:14655
autorun
I have no idea where this is coming from, and how to start tracking it down. Any ideas?
I think I tracked it down. It was because we were setting .html() with jQuery and blowing away:
<script id="metamorph-XXX-start" type="text/x-placeholder"></script>
Tags.

Categories

Resources