0

I am trying to check whether the Native app is installed or not , If it is not I have to prompt the user to download it from the webpage. For chrome I used to achieve by checking the error messages from runtime.LastError. However in case of Firefox it gives error only in console No such native application extension_name and not catching it in the runtime.LastError method.

Is there any way that we can identify whether corresponding Native app is installed or not ? I am facing issue when Native app is not installed and browser.runtime.lastError is not giving any error.

Can you please suggest if there is any way in Firefox Webextension that we can catch such errors and identify it in code whether the corresponding Native app is installed or not on the user machine.

It will really helpful if someone can provide some info on this.

for e.g. :

startNativeApp: function(force){
        // note that when the native app is opened and ready, it will call "_ABC_onAgentReady"
        ABC.log('Starting native app.');
        if (!ABC.appConnected) {
            try {
                ABC.nativeAppPort = browser.runtime.connectNative(_ABC_native_app_id);
                ABC.nativeAppPort.onMessage.addListener(ABC.onNativeMessageReceived);
                ABC.nativeAppPort.onDisconnect.addListener(ABC.onNativeAppDisconnected);
                ABC.appInstalled = true;
                ABC.appConnected = true;
            } catch(e) {
                ABC.log('Error starting native app: ' + e.message, 'ERR');
            }
        } else if (force === true) {
            ABC.log('Native app is already running; attempting to stop and will restart in 750ms.');
            ABC.stopNativeApp();
            setTimeout(function() { ABC.startNativeApp(true); }, 750);
        }
},


onNativeAppDisconnected: function(message) {
        console.log("ABC LastError : "+browser.runtime.lastError);
        console.log("ABC LastError : "+ABC.nativeAppPort.error);
        console.log("ABC LastError : "+JSON.stringify(message));
        ABC.appConnected = false;
        ABC.nativeAppPort = null;
        ABC.appInstalled = false;
        if (browser.runtime.lastError && (browser.runtime.lastError.message.indexOf("No such native application") !== -1 )) {
            ABC.appInstalled = false;
        }
        // cleanup: reset the sig data so that it is re-requested on the next scan
        _ABC_sa_data = "";
        _ABC_sigs = "";
        if (browser.storage && browser.storage.local) {
            browser.storage.local.set({ uid: _ABC_be_uid }, null);
        }

        ABC.log('Send message to page to stop.');
        ABC.sendMessageToPage({ onNativeAppDisconnected: '' });
        ABC.log('Native app disconnected.');
    },
rohan
  • 161
  • 1
  • 1
  • 10
  • Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the [ask] page for help clarifying this question. – Makyen Jan 09 '17 at 06:41
  • When native host is not installed or registry entry is not done and then if i try to connect the web extension (js part) to native app it gives me error in web console that "No such native application" which is correct, I want to check the same through in my js code whether native app is installed or not , If there is any way that i can get the message in response or in exceptions ? – rohan Jan 09 '17 at 06:53
  • Then it sounds like what we need is to see your code. My next comment will be a brief description of what is needed. It might sound like a lot, but we need to be able to understand what is going on and why you are not getting some error. While it would normally be needed, lets try it without the native app first (or pick a generic native (non existing?) program that results in the same thing). – Makyen Jan 09 '17 at 06:58
  • Please [edit] the question to be on-topic: include a **complete** [mcve] that *duplicates the problem*. Including a *manifest.json*, some of the background/content/popup scripts/HTML. Questions seeking debugging help ("**why isn't this code working?**") must include: ►the desired behavior, ►a specific problem or error *and* ►the shortest code necessary to reproduce it **in the question itself**. Questions without a clear problem statement are not useful to other readers. See: "**How to create a [mcve]**", [What topics can I ask about here?](http://stackoverflow.com/help/on-topic), and [ask]. – Makyen Jan 09 '17 at 06:58
  • The reason that a [mcve] is required is that *we want to help*. It is **much** easier to help if we don't have to recreate any of the code needed to duplicate the problem. This is code that you already have. So, please help us to help you and provide a *complete* [mcve] that duplicates the problem. Without a [mcve], the amount of effort required to even begin to help you is **much** higher, which *significantly* reduces the number of people willing/able to help you. Even if we put out the extra effort, we have to *guess* at significant portions of what your problem might be. – Makyen Jan 09 '17 at 06:59
  • Why are you unable to get the error from `runtime.lastError` on Firefox? Are you using the same code on Firefox as you are in Chrome? You said you were able to do so on Chrome. With the same code as on Chrome, what is the value of `runtime.lastError` in Firefox? – Makyen Jan 09 '17 at 07:04
  • runtime.lastError is null in case of firefox , It seems that it is not catching the error in lastError – rohan Jan 09 '17 at 07:57
  • What are the various console.log message that you see when you run this code? – Makyen Jan 09 '17 at 20:49
  • You have stated that you have this working in Chrome. Why did you re-code everything to use `browser.*` instead of `chrome.*`? It would be much easier to maintain one code base, where you use `chrome.*` throughout and have it run on both Chrome and Firefox using the same code. There are some differences, but that is usually something that you can easily handle by detecting if you are in Chrome vs. Firefox and just use the appropriate special case. – Makyen Jan 09 '17 at 20:52
  • This is the only error message I am getting : No such native application com.abc.firefox NativeMessaging.jsm:188 this.NativeApp – rohan Jan 10 '17 at 19:14
  • Which and *exactly* what do the `console.logs()` show? I can assume, but which line is the error generated on (presumably the `browser.runtime.connectNative()`)? Please [edit] this information into the question. Please provide a **complete** [mcve] that duplicates the problem so we can test this ourselves. – Makyen Jan 10 '17 at 19:52
  • 1
    Have you tried using the `chrome.*` APIs instead of `browser.*`? – Makyen Jan 10 '17 at 20:11

3 Answers3

0

Issue here was that port.error was not giving any error response in Firefox versions less than 52 , Due to which I was facing problem in identifying whether native app is installed or not.

After discussion on Mozilla Community (https://discourse.mozilla-community.org/t/firefox-native-messaging-runtime-lasterror-not-giving-any-errors-in-case-of-no-native-application-installed-on-connectnative/12880/4) , we found that it is actually missed and a bug is already reported : https://bugzilla.mozilla.org/show_bug.cgi?id=12994116 which will be resolved in Firefox 52.

However , I need to support Firefox 50 also , so the alternate I am using is to call native application in starting to find out whether it is installed or not.

If I got back response than it is installed otherwise it is not. However specific error messages will be available from Firefox52.

rohan
  • 161
  • 1
  • 1
  • 10
0

Right now at chrome 109 the following approaches won't work after connectNative:

  1. chrome.runtime.lastError. The error is printed because it is visible in the log but right after the call it is undefined.
  2. console.error = function (arg) {/**/}. Is not working to replace the default function.
  3. port.name is "" in both cases (error or no error).
  4. port.onDisconnect is not called if the application is missing.

The only solution left is to call a third checker:

const promise=chrome.runtime.sendNativeMessage("appname", { /*text: ""*/ });//,check_response
promise.then(check_response,check_error);
Sam
  • 91
  • 1
  • 5
-1

In Firefox there is no runtime.lastError.

The listener function you pass to runtime.Port.onDisconnect isn't passed the message, it's passed the port itself.

You then want port.error.

See the documentation for onDisconnect here https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime/Port

efhard
  • 1