Bug 1018320 - RequestSync API - patch 7 - reject promise when an exception is thrown, r=fabrice

This commit is contained in:
Andrea Marchesini 2015-01-13 09:53:26 +00:00
parent 3cc78a6424
commit 0a73d8f76f
4 changed files with 51 additions and 13 deletions

View File

@ -470,7 +470,7 @@ SystemMessageInternal.prototype = {
true,
null);
this._rejectPendingPromises(manifestURL);
this._rejectPendingPromisesFromManifestURL(manifestURL);
}
break;
}
@ -482,7 +482,7 @@ SystemMessageInternal.prototype = {
msg.manifestURL,
false,
msg.pageURL);
this._rejectPendingPromises(msg.manifestURL);
this._rejectPendingPromisesFromManifestURL(msg.manifestURL);
break;
}
case "SystemMessageManager:GetPendingMessages":
@ -554,10 +554,14 @@ SystemMessageInternal.prototype = {
{
debug("received SystemMessageManager:HandleMessageDone " + msg.type +
" with msgID " + msg.msgID + " for " + msg.pageURL +
" @ " + msg.manifestURL);
" @ " + msg.manifestURL + " - promise rejected: " + msg.rejected);
// Maybe this should resolve a pending promise.
this._resolvePendingPromises(msg.msgID);
// Maybe this should resolve/reject a pending promise.
if (msg.rejected) {
this._rejectPendingPromises(msg.msgID);
} else {
this._resolvePendingPromises(msg.msgID);
}
// A page has finished handling some of its system messages, so we try
// to release the CPU wake lock we acquired on behalf of that page.
@ -644,7 +648,7 @@ SystemMessageInternal.prototype = {
}
}
this._rejectPendingPromises(manifestURL);
this._rejectPendingPromisesFromManifestURL(manifestURL);
debug("Finish updating registered pages for an uninstalled app.");
break;
@ -789,7 +793,20 @@ SystemMessageInternal.prototype = {
}
},
_rejectPendingPromises: function(aManifestURL) {
_rejectPendingPromises: function(aMessageID) {
if (!this._pendingPromises.has(aMessageID)) {
debug("Unknown pendingPromise messageID. This seems a bug!!");
return;
}
let obj = this._pendingPromises.get(aMessageID);
if (!--obj.counter) {
obj.rejectPromiseCb();
this._pendingPromises.delete(aMessageID);
}
},
_rejectPendingPromisesFromManifestURL: function(aManifestURL) {
for (var [i, obj] of this._pendingPromises) {
if (obj.manifestURL == aManifestURL) {
obj.rejectPromiseCb();

View File

@ -95,9 +95,14 @@ SystemMessageManager.prototype = {
}
}
aDispatcher.handler
.handleMessage(wrapped ? aMessage
: Cu.cloneInto(aMessage, this._window));
let message = wrapped ? aMessage : Cu.cloneInto(aMessage, this._window);
let rejectPromise = false;
try {
aDispatcher.handler.handleMessage(message);
} catch(e) {
rejectPromise = true;
}
this._isHandling = false;
aDispatcher.isHandling = false;
@ -111,7 +116,8 @@ SystemMessageManager.prototype = {
{ type: aType,
manifestURL: self._manifestURL,
pageURL: self._pageURL,
msgID: aMessageID });
msgID: aMessageID,
rejected: rejectPromise });
}
if (!this._promise) {
@ -119,7 +125,10 @@ SystemMessageManager.prototype = {
sendResponse();
} else {
debug("Using the promise to postpone the response.");
this._promise.then(sendResponse, sendResponse);
this._promise.then(sendResponse, function() {
rejectPromise = true;
sendResponse();
});
this._promise = null;
}

View File

@ -678,6 +678,7 @@ this.RequestSyncService = {
}, timeout, Ci.nsITimer.TYPE_ONE_SHOT);
// Sending the message.
debug("Sending message.");
let promise =
systemMessenger.sendMessage('request-sync',
this.createPartialTaskObject(aObj.data),

View File

@ -15,7 +15,7 @@
var multiShotCounter = 0;
function maybeDone() {
if (oneShotCounter == 1 && multiShotCounter == 3) {
if (oneShotCounter == 1 && multiShotCounter == 5) {
runTests();
}
}
@ -57,7 +57,18 @@
}));
} else if (multiShotCounter == 2) {
// The second time we don't reply at all.
info("Setting a promise object without resolving it.");
navigator.mozSetMessageHandlerPromise(new Promise(function(a, b) {}));
} else if (multiShotCounter == 3) {
info("Throwing an exception.");
// Now we throw an exception
SimpleTest.expectUncaughtException();
throw "Booom!";
} else {
info("Setting a promise object and reject it.");
navigator.mozSetMessageHandlerPromise(new Promise(function(a, b) {
setTimeout(b, 0);
}));
}
maybeDone();