Bug 744627 - TokenServerClient should not call callbacks twice; r=rnewman

This commit is contained in:
Gregory Szorc 2012-04-11 18:51:48 -07:00
parent d53442f051
commit a8ac3f9cf5
2 changed files with 63 additions and 3 deletions

View File

@ -164,3 +164,43 @@ add_test(function test_rich_media_types() {
server.stop(run_next_test);
});
});
add_test(function test_exception_during_callback() {
_("Ensure that exceptions thrown during callback handling are handled.");
let server = httpd_setup({
"/foo": function(request, response) {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "application/json");
let body = JSON.stringify({
id: "id",
key: "key",
api_endpoint: "foo",
uid: "uid",
});
response.bodyOutputStream.write(body, body.length);
}
});
let url = TEST_SERVER_URL + "foo";
let client = new TokenServerClient();
let cb = Async.makeSpinningCallback();
let callbackCount = 0;
client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
do_check_eq(null, error);
cb();
callbackCount += 1;
throw new Error("I am a bad function!");
});
cb.wait();
// This relies on some heavy event loop magic. The error in the main
// callback should already have been raised at this point.
do_check_eq(callbackCount, 1);
server.stop(run_next_test);
});

View File

@ -16,6 +16,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://services-common/log4moz.js");
Cu.import("resource://services-common/preferences.js");
Cu.import("resource://services-common/rest.js");
Cu.import("resource://services-common/utils.js");
const Prefs = new Preferences("services.common.tokenserverclient.");
@ -164,13 +165,32 @@ TokenServerClient.prototype = {
return;
}
let self = this;
function callCallback(error, result) {
if (!cb) {
self._log.warn("Callback already called! Did it throw?");
return;
}
try {
cb(error, result);
} catch (ex) {
self._log.warn("Exception when calling user-supplied callback: " +
CommonUtils.exceptionStr(ex));
}
cb = null;
}
try {
client._processTokenResponse(this.response, cb);
client._processTokenResponse(this.response, callCallback);
} catch (ex) {
this._log.warn("Error processing token server response: " +
CommonUtils.exceptionStr(ex));
let error = new TokenServerClientError(ex);
error.response = this.response;
cb(error, null);
return;
callCallback(error, null);
}
});
},