2

This is a "please help me understand X" question, not a "please help me fix X" question.

I was doing some work on a site with a legacy proprietary CMS that only works with jQuery 1.4.4 (ugh) when I realised my code must be hitting an error, but no error messages were showing in the console (in all browsers I tried - Chrome, Firefox, Safari, IE...).

Lots of trial and error later, I figured out that within any code triggered by jQuery 1.4.4's mouseenter event (and therefore also its hover shorthand), errors weren't being shown in the console. console.log still logged just fine, and the code would fall over as would be expected, but silently.

I don't understand how this is possible. I'd like to know how it is possible so that, if in future I end up in a similar position where code is hitting silent errors, I know what to look for - and so I know how to avoid causing a similar situation by accident.


Prior research

I've tried searching for old jQuery bug reports, which might include relevant information, but I couldn't find any. I've read through a lot of SO questions from people trying to cause JS error suppression, but the answers suggest it's a user preference that couldn't apply to some lines of code but not others. I've looked through the jQuery 1.4.4 source code, but nothing looks relevant to my eye.

I'm not interested in fixing the problem (that's as simple as updating jQuery) - but I'd like to understand what causes this to happen, because I can't see how it's possible.


Simple live demo

    $(document).ready(function(){
     $('.mouseenter').mouseenter(function(){
      console.log("FAIL .mouseenter");
      FAIL; // fails silently
      console.log("hit error, so this code isn't reached");
     });
     $('.mouseover').mouseover(function(){
      console.log("FAIL .mouseover");
      FAIL; // shows error as expected
      console.log("hit error, so this code isn't reached");
     });
    });
div { height: 60px; background: #c1c1c1; margin: 10px; padding: 10px; }
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>

</head>
<body>
<div class="mouseenter">mouseenter - hides error on hover</div>
<div class="mouseover">mouseover - shows error on hover</div>
</body>

After mouseovering around the console looks like this - mouseover shows error in console, mouseenter doesn't, but both hit the error and fall over:

enter image description here

user56reinstatemonica8
  • 27,132
  • 16
  • 87
  • 109

2 Answers2

1

The old jQuery 1.4.4 used to wrap the code that did the mouseenter/mouseleave events in a try{}catch(e){} that throws away the error: See https://github.com/jquery/codeorigin.jquery.com/blob/master/cdn/jquery-1.4.4.js#L2487

You'll see that behavior until the effects rewrite that went in for jQuery 1.7.

gnarf
  • 101,278
  • 24
  • 124
  • 158
0

To add to gnarf's excellent answer - if you do find yourself in this situation, where you're not getting error messages due to a library calling your code within a try{}catch(){} that discards the error, and editing or upgrading the library is not an option, you can force the errors to show by wrapping all your code in another try{}catch(){} block that sneaks the error past the catch() by sending it straight to console.error(), for example:

            $('.mouseenter').mouseenter(function(){
                    try{
                            // your code
                    } catch(e){
                            console.error(e);
                    }
            });

If you're in the unfortunate position of needing to leave this in production code or of using IE during development, you should be aware that in many versions of IE console is by default undefined unless developer tools is open, so to avoid your error handling causing errors, instead use if(window.console){console.error(e);} or use a robust proper fix.


Demo

    $(document).ready(function(){
            $('.mouseenter').mouseenter(function(){
                    try{
                            console.log("FAIL .mouseenter");
                            var fail = FAIL; // fails silently
                            console.log("...");
                    } catch(e){
                            console.error(e);
                    }
            });
            $('.mouseover').mouseover(function(){
                    console.log("FAIL .mouseover");
                    var fail = FAIL; // shows error as expected
                    console.log("...");
            });
    });
div { height: 60px; background: #c1c1c1; margin: 10px; padding: 10px; }
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>

</head>
<body>
<div class="mouseenter">mouseenter - hides error on hover</div>
<div class="mouseover">mouseover - shows error on hover</div>
</body>
Community
  • 1
  • 1
user56reinstatemonica8
  • 27,132
  • 16
  • 87
  • 109