2

I have a single page application created with Durandal.js and I'm having a heck of a time debugging an issue with IE11 and Durandal's app.showMessage(...) and app.showDialog(...) methods. Currently the app runs fine in Chrome, FireFox and IE 9 and 10, but in IE11 I am running into an issue where my app hangs when trying to call up a dialog via app.showDialog(...). If I open the dev tools before going to my app it all runs just fine. If I try to go to the app, run the code that results in app.showDialog firing and THEN open the dev tools and try to run that same code I do get access to the error that is occurring, but it's not very helpful. The actual error reads as SCRIPT5007: Unable to get property 'name' of undefined or null reference and it's at File: system.js, Line: 90, Column: 13. The code from that area of system.js relates to Durandal's logError method which looks like this:

var logError = function(error) {
    if(error instanceof Error){
        throw error;
    }
    throw new Error(error);
};

The error stack appears as included in the attached image (located at the bottom of my question). Sorry I had to use an alert to get the full error stack since otherwise the logged version is cutoff.

I have also tried a few things including ensuring my doctype is correctly decalred with <!DOCTYPE html> at the top of my index.html file, I have added <meta http-equiv="X-UA-Compatible" content="IE=edge"> to index.html and I have also tried to add my own console object to catch any debug code that may still be in the app via the following script that I found here: https://stackoverflow.com/a/12307201/4367226

<script type="text/javascript">
    // IE9 fix
    if(!window.console) {
        alert("There isn't a console!");
        var console = {
            log: function( x ){},
            warn: function( x ){},
            error: function( err ){
                alert( "Error from console object:" );
                alert( err );
                alert( err.stack );
            },
            time: function(){},
            timeEnd: function(){}
        };
    }
</script>

I've also ensured that the app has a "cache buster" (related to https://stackoverflow.com/a/25170531/4367226) by adding

$.ajaxSetup({cache:false});

to my app.

I have also tried to remove the fade class from my modals without success (as suggested here: https://stackoverflow.com/a/25717025/4367226).

Further details - the app is running Durandal 2.0.1, Twitter Bootstrap 2.3.2 and jQuery 1.10.2.

Any help would be much appreciated and let me know if I can help clarify anything.

Update

After further investigation and debugging I have been able to find the offending line of code in the bootstrap-modalmanager.js file's init method and it is jQuery related (so I added that tag back to my question):

init: function (element, options) {
        this.$element = $(element);
        this.options = $.extend({}, $.fn.modalmanager.defaults, this.$element.data(), typeof options == 'object' && options);
        this.stack = [];
        this.backdropCount = 0;

        if (this.options.resize) {
            var resizeTimeout,
                that = this;

            $(window).on('resize.modal', function(){
                resizeTimeout && clearTimeout(resizeTimeout);
                resizeTimeout = setTimeout(function(){
                    for (var i = 0; i < that.stack.length; i++){
                        that.stack[i].isShown && that.stack[i].layout();
                    }
                }, 10);
            });
        }
    },

In the line that reads this.options = $.extend({}, $.fn.modalmanager.defaults, this.$element.data(), typeof options == 'object' && options); from above the this.$element.data() bit seems to be blowing things up. That is where the error is coming from, but I have no idea why it would work with dev tools open, but throws an error otherwise.

Update 2

After continued digging I found that jQuery 1.10.2's jQuery.fn.extend function is broken. The function would try to iterate over an element's attributes and this part of the code: name = attrs[i].name; would allow the code to try and access name of a (sometimes in IE11) null or undefined value - hence the error that I was seeing. That code has been fixed in jQuery 1.11.3 (and it even references the fact that sometimes IE11 the attrs element can be null in the code), but unfortunately the upgraded version breaks other things in my app, so I have replaced the jQuery 1.10.2's jQuery.fn.extend function with version 1.11.3's function of the same name.

error callstack

Community
  • 1
  • 1
jbgarr
  • 1,378
  • 1
  • 12
  • 23
  • Have you tried [InPrivate](http://windows.microsoft.com/en-us/windows/what-is-inprivate-browsing#1TC=windows-7) browsing? To me it still sounds like a caching issue, when you have the dev tool open there is an option to disable cache, if you have that set it might explain the difference behaviors. InPrivate (Tools/InPrivate Browsing) should give you a completely new session just like it's your first time to the page removing the caching question. – Frank May 15 '15 at 12:01
  • Thanks for the suggestion Frank. I hadn't tried to use InPrivate browsing yet, but I just tested it and had no luck. I've actually been able to use the debugger to track down the offending line of code though and by commenting it out I have been able to use the app as expected. The offending line is located in `bootstrap-modalmanager.js`'s init method, and reads as follows: `this.options = $.extend({}, $.fn.modalmanager.defaults, this.$element.data(), typeof options == 'object' && options);`. The problem seems to be related to the `this.$element.data()` portion of that code. – jbgarr May 15 '15 at 16:26
  • Any reason why running `this.$element.data()` would work fine with dev tools open, but running it without dev tools would result in an error? That seems to be the source of my issue which seems very strange. More investigation to do here... – jbgarr May 15 '15 at 16:33
  • After a little google searching it seems IE11 has a number of issues with the .data() function. You might want to try, if possible, to upgrade to the latest jquey and see if that helps. – Frank May 15 '15 at 17:28
  • Ok, thanks Frank. I've done an initial test with the newest version of jquery's 1.x code and that seems to have solved the initial issue, although now there seems to be something else going on that I'll have to take a look at. At least the update seems like a fix as long as I can get it to upgrade without breaking anything else :) – jbgarr May 15 '15 at 18:48
  • So unfortunately upgrading jquery to the newest 1.x version breaks more things and opens a bigger can of worms :( – jbgarr May 15 '15 at 19:26

1 Answers1

2

So after many, many hours of debugging I have found the cause of my issue. It's related to jQuery 1.10.2's jQuery.data function. In that function there is a for loop that iterates over an element's attributes and tries to access .name of a (sometimes in IE11) null or undefined value.

That bug was fixed in jQuery 1.11.3's version of jQuery.data, but unfortunately I couldn't use the full upgraded version of jQuery without breaking other parts of the app. Instead I simply replaced jQuery 1.10.2's jQuery.data function with the updated version from jQuery 1.11.3.

This is not the best solution (I would rather not have to hack the core of jQuery and have Frankenstein code in my app), but it works.

I'm also still puzzled as to why my old code worked fine in IE11 with the dev tools open, but would fail otherwise. Maybe dev tools adds something to the body element's attributes that prevented the error from happening?

jbgarr
  • 1,378
  • 1
  • 12
  • 23
  • I've had this issue with console.log not being defined and the app secretly dying, any chance it's something like that? – Thomas Taylor May 18 '15 at 17:49
  • @ThomasTaylor I don't think `console.log` was the problem in my case. I know it can be a problem though so in order to ensure that wasn't the cause of my issue I added some code that would create a console object in the case that one didn't already exist. That way any calls to `console.log` would be caught by my console object and avoid killing my app. Thanks for the suggestion though! – jbgarr May 18 '15 at 23:39