Index: polyfill.js |
=================================================================== |
--- a/polyfill.js |
+++ b/polyfill.js |
@@ -38,16 +38,42 @@ |
"tabs.sendMessage", |
"tabs.update", |
"webNavigation.getAllFrames", |
"webRequest.handlerBehaviorChanged", |
"windows.create", |
"windows.update" |
]; |
+ // Errors that occur only when we show an interest in the response from an |
+ // API call. |
+ const noFulfillmentErrors = [ |
+ "The message port closed before a response was received." |
+ ]; |
+ |
+ const fulfillmentInterestFlag = Symbol(); |
Manish Jethani
2017/10/19 01:59:46
We use a symbol here so it becomes like a private
|
+ |
+ function SpecialPromise(...args) |
+ { |
+ return Reflect.construct(Promise, args, SpecialPromise); |
Manish Jethani
2017/10/19 01:59:46
Essentially an extended promise.
|
+ } |
+ |
+ SpecialPromise.prototype = Object.create( |
+ Object.assign({}, Promise.prototype, { |
+ then(...args) |
+ { |
+ // Set this flag to indicate that there is interest in the fulfillment |
+ // of this promise. |
+ this[fulfillmentInterestFlag] = true; |
+ |
+ return Promise.prototype.then.apply(this, args); |
+ } |
+ }) |
+ ); |
+ |
function wrapAPI(api) |
{ |
let object = browser; |
let path = api.split("."); |
let name = path.pop(); |
for (let node of path) |
{ |
@@ -66,27 +92,42 @@ |
// If the last argument is undefined, we drop it from the list assuming |
// it stands for the optional callback. We must do this, because we have |
// to replace it with our own callback. If we simply append our own |
// callback to the list, it won't match the signature of the function and |
// will cause an exception. |
if (typeof args[args.length - 1] == "undefined") |
args.pop(); |
- return new Promise((resolve, reject) => |
+ let promise = new SpecialPromise((resolve, reject) => |
{ |
func.call(object, ...args, result => |
{ |
let error = browser.runtime.lastError; |
if (error) |
+ { |
+ // If is this an error we got only because we passed in a callback |
+ // and there's no actual interest in the response, ignore the |
+ // error. |
+ if (noFulfillmentErrors.includes(error.message) && |
+ !promise[fulfillmentInterestFlag]) |
+ { |
+ return; |
+ } |
+ |
reject(error); |
+ } |
else |
+ { |
resolve(result); |
+ } |
}); |
}); |
+ |
+ return promise; |
}; |
} |
function shouldWrapAPIs() |
{ |
try |
{ |
return !(browser.storage.local.get([]) instanceof Promise); |