Bug 1287007 - Improve errors for non-existing remote APIs r=billm
Currently, if the remote implementation is missing, the next unhelpful
error message is logged to the console:
"TypeError: findPathInObject(...) is not a function" or
"TypeError: findPathInObject(...) is undefined", etc.
This commit makes the message more useful:
"WebExtension API tabs.create not found (it may be unimplemented by Firefox)"
MozReview-Commit-ID: FhPEYKSjnLm
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -363,32 +363,35 @@ class ProxyContext extends BaseContext {
if (this.unloaded) {
return;
}
super.unload();
Management.emit("proxy-context-unload", this);
}
}
-function findPathInObject(obj, path) {
+function findPathInObject(obj, path, printErrors = true) {
for (let elt of path.split(".")) {
// If we get a null object before reaching the requested path
// (e.g. the API object is returned only on particular kind of contexts instead
// of based on WebExtensions permissions, like it happens for the devtools APIs),
// stop searching and return undefined.
// TODO(robwu): This should never be reached. If an API is not available for
// a context, it should be declared as such in the schema and enforced by
// `shouldInject`, for instance using the same logic that is used to opt-in
// to APIs in content scripts.
// If this check is kept, then there is a discrepancy between APIs depending
// on whether it is generated locally or remotely: Non-existing local APIs
// are excluded in `shouldInject` by this check, but remote APIs do not have
// this information and will therefore cause the schema API generator to
// create an API that proxies to a non-existing API implementation.
if (!obj || !(elt in obj)) {
+ if (printErrors) {
+ Cu.reportError(`WebExtension API ${path} not found (it may be unimplemented by Firefox).`);
+ }
return null;
}
obj = obj[elt];
}
return obj;
}
@@ -699,17 +702,17 @@ GlobalManager = {
return context.extension.hasPermission(permission);
},
shouldInject(namespace, name, allowedContexts) {
// Do not generate content script APIs, unless explicitly allowed.
if (context.envType === "content_parent" && !allowedContexts.includes("content")) {
return false;
}
- return findPathInObject(apis, namespace) !== null;
+ return findPathInObject(apis, namespace, false) !== null;
},
getImplementation(namespace, name) {
let pathObj = findPathInObject(apis, namespace);
return new LocalAPIImplementation(pathObj, name, context);
},
};
Schemas.inject(dest, schemaWrapper);