Bug 1287007 - Improve errors for non-existing remote APIs r=billm
authorRob Wu <rob@robwu.nl>
Thu, 01 Sep 2016 21:14:31 -0700
changeset 428695 fbbeab9bd95bca3c7f97e3cadebd42d93c7610bb
parent 428694 5e6462c7563d934c4bc780a567663bba4d8f0f47
child 428696 b91a39e959ffb29b8da8d41684181d17f92fef80
push id33405
push userbcampen@mozilla.com
push dateMon, 24 Oct 2016 15:32:53 +0000
reviewersbillm
bugs1287007
milestone52.0a1
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
toolkit/components/extensions/Extension.jsm
--- 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);