From ad6a94c3f1747829082b85fd53ee2efbae879707 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Go=C5=82e=CC=A8biowski?= Date: Wed, 29 Jun 2016 14:19:04 +0200 Subject: [PATCH] Core: Re-throw errors that happened in callbacks wrapped in jQuery ready Also, expose jQuery.readyException that allows to overwrite the default ready error handler. Fixes gh-3174 Closes gh-3210 --- src/core/ready.js | 11 +++++++- src/core/readyException.js | 13 ++++++++++ test/unit/core.js | 52 +++++++++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src/core/readyException.js diff --git a/src/core/ready.js b/src/core/ready.js index bb4e222d3..53b1b2da7 100644 --- a/src/core/ready.js +++ b/src/core/ready.js @@ -1,6 +1,7 @@ define( [ "../core", "../var/document", + "../core/readyException", "../deferred" ], function( jQuery, document ) { @@ -11,7 +12,15 @@ var readyList = jQuery.Deferred(); jQuery.fn.ready = function( fn ) { - readyList.then( fn ); + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); return this; }; diff --git a/src/core/readyException.js b/src/core/readyException.js new file mode 100644 index 000000000..72bdd90b5 --- /dev/null +++ b/src/core/readyException.js @@ -0,0 +1,13 @@ +define( [ + "../core" +], function( jQuery ) { + +"use strict"; + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + +} ); diff --git a/test/unit/core.js b/test/unit/core.js index 8ad3c86ce..8c0f8640e 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -1,4 +1,12 @@ -QUnit.module( "core", { teardown: moduleTeardown } ); +QUnit.module( "core", { + setup: function() { + this.sandbox = sinon.sandbox.create(); + }, + teardown: function() { + this.sandbox.restore(); + return moduleTeardown.apply( this, arguments ); + } +} ); QUnit.test( "Basic requirements", function( assert ) { assert.expect( 7 ); @@ -1709,3 +1717,45 @@ QUnit.test( "Iterability of jQuery objects (gh-1693)", function( assert ) { assert.ok( true, "The browser doesn't support Symbols" ); } } ); + +QUnit[ jQuery.Deferred ? "test" : "skip" ]( "jQuery.readyException (original)", function( assert ) { + assert.expect( 1 ); + + var message; + + this.sandbox.stub( window, "setTimeout", function( fn ) { + try { + fn(); + } catch ( error ) { + message = error.message; + } + } ); + + jQuery( function() { + throw new Error( "Error in jQuery ready" ); + } ); + assert.strictEqual( + message, + "Error in jQuery ready", + "The error should have been thrown in a timeout" + ); +} ); + +QUnit[ jQuery.Deferred ? "test" : "skip" ]( "jQuery.readyException (custom)", function( assert ) { + assert.expect( 1 ); + + var done = assert.async(); + + this.sandbox.stub( jQuery, "readyException", function( error ) { + assert.strictEqual( + error.message, + "Error in jQuery ready", + "The custom jQuery.readyException should have been called" + ); + done(); + } ); + + jQuery( function() { + throw new Error( "Error in jQuery ready" ); + } ); +} ); -- 2.39.5