jQuery recently had a major update to version 3. With it came a subtle change that might cause some headaches for you if your aren’t prepared for it.
The [CODE]$(document).ready[/CODE] function now uses a jQuery deferred promise internally.This is probably for the best but it has an unfortunate side effect of swallowing any exceptions that happen inside the callback.
Take for example this typical jQuery hello world application.
-- CODE language-html --
Now see what happens when we introduce an error into our code to simulate an uncaught exception:
throw new Error('boom!')
Just like in jQuery 2 we get a blank page and the application is completely broken, but unlike jQuery 2 the console is also completely empty.
Before we would have had an error thrown and it would have been obvious what was broken. Now, without an uncaught exception, not only is debugging harder, but we also won’t see the error automatically reported to Bugsnag. There could be a broken page in production right now and we wouldn’t be able to rely on our existing instrumentation to find it.
There are two ways around this problem. Deciding which one is better depends on how much of the application code is dependent on jQuery.
jQuery 3.0 now formally supports the promise syntax for listening to [CODE].ready()[/CODE].
throw new Error('boom');
By using the promise syntax for initialization of the application we can catch errors and re-throw them. This will not only show them in the browser console, but also cause them to be caught by the Bugsnag exception tracker.
It is important that when software fails, it fails loudly, explicitly, and in a way that is obvious to track down. Otherwise problems linger in silence without your knowledge. jQuery 3.0 has made great efforts to be more explicit about failures but there are still some gotchas that can trip up the unsuspecting application developer if they aren’t expecting them.