From 7e2e2db806f621c61851bc9df32e398a5a6d345e Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Thu, 17 Nov 2016 12:59:09 -0800 Subject: [PATCH] mw.loader: For using() errors, reject Promise instead of throwing The "Unknown module" and "Circular dependency" errors both come from the resolve() function. Add a try/catch around that and reject the promise if caught. Bug: T131612 Change-Id: I900909cd00df6a51f3bf1f3df91bdb610c11c446 --- resources/src/mediawiki/mediawiki.js | 9 +++- .../mediawiki/mediawiki.loader.test.js | 53 +++++++++++++++---- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/resources/src/mediawiki/mediawiki.js b/resources/src/mediawiki/mediawiki.js index 4dce192cf3..dd3d6dee64 100644 --- a/resources/src/mediawiki/mediawiki.js +++ b/resources/src/mediawiki/mediawiki.js @@ -1168,6 +1168,7 @@ * @private * @param {string[]} modules Array of string module names * @return {Array} List of dependencies, including 'module'. + * @throws {Error} If an unregistered module or a dependency loop is encountered */ function resolve( modules ) { var resolved = []; @@ -1993,8 +1994,12 @@ deferred.fail( error ); } - // Resolve entire dependency map - dependencies = resolve( dependencies ); + try { + // Resolve entire dependency map + dependencies = resolve( dependencies ); + } catch ( e ) { + return deferred.reject( e ).promise(); + } if ( allReady( dependencies ) ) { // Run ready immediately deferred.resolve( mw.loader.require ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js index 505d9a17fb..92d13260e9 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js @@ -134,6 +134,48 @@ } ); } ); + QUnit.test( '.using() Error: Circular dependency', function ( assert ) { + mw.loader.register( [ + [ 'test.circle1', '0', [ 'test.circle2' ] ], + [ 'test.circle2', '0', [ 'test.circle3' ] ], + [ 'test.circle3', '0', [ 'test.circle1' ] ] + ] ); + mw.loader.using( 'test.circle3' ).then( + function done() { + assert.ok( false, 'Unexpected resolution, expected error.' ); + }, + function fail( e ) { + assert.ok( /Circular/.test( String( e ) ), 'Detect circular dependency' ); + } + ); + } ); + + QUnit.test( '.load() - Error: Circular dependency', function ( assert ) { + mw.loader.register( [ + [ 'test.circleA', '0', [ 'test.circleB' ] ], + [ 'test.circleB', '0', [ 'test.circleC' ] ], + [ 'test.circleC', '0', [ 'test.circleA' ] ] + ] ); + assert.throws( function () { + mw.loader.load( 'test.circleC' ); + }, /Circular/, 'Detect circular dependency' ); + } ); + + QUnit.test( '.using() - Error: Unregistered', function ( assert ) { + mw.loader.using( 'test.using.unreg' ).then( + function done() { + assert.ok( false, 'Unexpected resolution, expected error.' ); + }, + function fail( e ) { + assert.ok( /Unknown/.test( String( e ) ), 'Detect unknown dependency' ); + } + ); + } ); + + QUnit.test( '.load() - Error: Unregistered (ignored)', 0, function ( assert ) { + mw.loader.load( 'test.using.unreg2' ); + } ); + QUnit.test( '.implement( styles={ "css": [text, ..] } )', 2, function ( assert ) { var $element = $( '
' ).appendTo( '#qunit-fixture' ); @@ -420,17 +462,6 @@ assert.strictEqual( mw.track.callCount, 1 ); } ); - QUnit.test( 'Circular dependency', 1, function ( assert ) { - mw.loader.register( [ - [ 'test.circle1', '0', [ 'test.circle2' ] ], - [ 'test.circle2', '0', [ 'test.circle3' ] ], - [ 'test.circle3', '0', [ 'test.circle1' ] ] - ] ); - assert.throws( function () { - mw.loader.using( 'test.circle3' ); - }, /Circular/, 'Detect circular dependency' ); - } ); - QUnit.test( 'Out-of-order implementation', 9, function ( assert ) { mw.loader.register( [ [ 'test.module4', '0' ], -- 2.20.1