I noticed an occasional error logged on disabling the bootstrapped addon.
function shutdown:
function shutdown(data, reason) {
forEachOpenWindow(unloadFromWindow);
Services.wm.removeListener(WindowListener);
Components.utils.unload('chrome://myaddon/content/main.jsm');
}
Sometimes, it came up with an error on disabling the addon:
NotFoundError: Node was not found main.jsm:112
Is it that the Components.utils.unload() is asynchronous?
1- Is that the case or is it due to some other issue?
2- If that is the case, how should it be dealt with?
3- Can the Components.utils.unload() be added to (processed in) the JSM that it is removing (removing itself)?
4- Any other suggestions?
Update:
Next test:
Disable -- no error
Enable/Disable -- 1 error (above)
Enable/Disable -- 2 error (above)
Enable/Disable -- 3 error (above)
Enable/Disable -- 4 error (above)
Enable/Disable -- 5 error (above)
Now that is strange ....
Update 2:
I found the problem.... typo/error in one of the listeners so it was NOT removed on shutdown() and with every subsequent enable/disable one more listeners was added...that was why the number of errors increased each time :)
Is Components.utils.unload asynchronous in Firefox bootstrapped extensions?
Cu.unload is not asynchronous. But also, it might not do what you expect.
It will just instruct the module loader to forget about it. Any references to the module instance from other code will still work, i.e. the module instance will be alive until all other references to it are gone and it can be garbage collected.
In that regard it can seem like unload is kinda asynchronous.
3- Can the Components.utils.unload() be added to (processed in) the JSM that it is removing (removing itself)?
Yes, the module can Cu.unload on itself. Code after Cu.unload will still work (see also the first part of my answer).
Related
I have a group of three e2e tests which I am converting from Cypress 8.7 to 10.3 with the end goal of being able to take advantage of Cypress' component testing.
The tests all work both as a group and as individual specs (via --spec <path>) in 8.7.
After converting to 10.3, I have a spec which calls a common command which clicks a button (which the extension adds to a page), which fires its listener and calls chrome.runtime.sendMessage with a message to open the extension UI. In this particular case, the content script is handling its own message (which is technically redundant), but since there are other cases which communicate with the background script, we use the same sendMessage call for consistency (this works every time in the actual Chrome environment). To facilitate this, the background script has a listener which effectively sends the message back to the sending tab for messages it does not directly handle.
Spec 1: always works
Spec 2: always works when run alone with --spec, and never works when all the tests are run together
Spec 3: same as spec 2
I do not believe it is a race condition, as no amount of cy.wait() has been successful. I can verify that the portion of the content script registering the event with chrome.runtime.onMessage.addListener runs at the start of each spec (both alone and all together). However, it never runs when clicking the button (even when paused and manually clicking).
I have the extension manifest setup for the tests to only match the URLs being visited by cypress and have that combined with all_frames: true, resulting in the extension button only showing in the content window and not the overall Cypress chrome window. Logging document at both the listener registration and the click listener logs the same document, so I don't think it is a cross-frame issue.
Based on the available logging from the background script, my conclusion is that it effectively stops running (breakpoints at the beginning of its message handler no longer fire). However, there's nothing to indicate why that might be.
If I place all the tests from those other specs into one spec, that call works as expected (although the tests still fail, presumably due to some other state which is cleared between specs). Is there something I can do to find out why the background script stops running between specs in Cypress 10.3?
One final note is that there are some uncaught and ignored errors in the background script. I am working on cleaning those up, but these tests have always worked in the past despite that (and work when run each spec is run alone), so I'm at a loss.
I have taken over an Electron project from another developer.
The problem I am facing is that the project does not show any errors. Even including something like throw "this is an error" does not produce any output on the main process or render process consoles or any sort of standard error popup.
I have checked to confirm that electron-unhandled is not in use and that nothing registers 'uncaughtException'.
What am I missing that could cause this behavior?
Search for: unhandledRejection
unhandledRejection : This will catch any thrown errors, or non fatal errors you have successfully handled via throw.
uncaughtException : This only catches fatal errors or errors that would crash your node instance
WebWorkers : There will be yet another console for webworkers if your using those.
package.json : Take a look in here at the script executed to start electron or however your starting it... Make sure the console is not being sent to a remote console. This feature would allow for debugging the application via Chrome/Firefox vs the standard console. Pretty common for electron apps. If is done via the startup command.
May look something like this:
process.on('unhandledRejection', function (err) {
});
Also, make sure you include any modules in your searching for suppressors as the issue may exist somewhere in the node_modules directory and many IDE's (mine does by default) exclude that directory in indexing/searches.
Another possible reason could be stdout and/or stderr redirection, the problem is this could be achieved by several ways so it's hard to suggest you what to check...
If there is some child_process call to launch a sub-process you could check the stdio array used, or you can check if some low level operation is performed against file descriptors 1 and 2...
Hope this helps.
Are you facing the problem as mentioned in this official thread. You may disable the original event listeners and manage the ELECTRON_BROWSER_WINDOW_ALERT event by my event listener.
Here is the solution
ipcMain.removeAllListeners("ELECTRON_BROWSER_WINDOW_ALERT")
ipcMain.on("ELECTRON_BROWSER_WINDOW_ALERT", (event, message, title)=>{
console.warn(`[Alert] ** ${title} ** ${message}`)
event.returnValue = 0 // **IMPORTANT!**
})
I'm trying to develop an HTA for extracting and processing the data from PDF files for a number of people in a large office. I've been looking into using the PDF.js package for this, but I've not been able to get it working.
I've forked the project and created an HTA version of the helloworld example with the compatibility.js file included. I can get an HTML version of this working on Firefox and IE11 through a gulp server, but the HTA doesn't give any output - no text, no error messages.
After peppering the source files with alert() statements, I've discovered that the original hello.js file is missing promise reject function, and that this fires when added, but here where my I meet the limits of my knowledge. I don't really know an awful lot about promises, so I don't understand why this one fails. Is this solvable or does it mean that the package simply won't run in an HTA?
EDIT:
I've been looking more into this and the failure doesn't make sense.
Tracing the logic through, the hello.js file calls the function api.getDocument from api.js. Following this back, there is only one return statement and the alert statement just before this line is running. However the fulfilled function is not triggering.
From my very limited understanding, the failure clause on a promise will be triggered from a throw() statement within the asynchronous operation. If that is the case then I would expect that operation to immediately cease and the reject function to trigger, but why would the line immediately before the return statement still run?
I did pursue one theory that this line from api.js was the one throwing the error:
}).catch(task._capability.reject);
To check this, I added an alert statement to the reject() function statement in util.js, but it did not trigger, so I can't tell where the error is coming from.
Is anyone able to give me any additional pointers to help me trace this down?
Solved!
By changing the compatibility setting to IE10 instead of IE9 (which I didn't know I could do) I got a more useful error in the right place. Looking more into this, this issue appears to be a duplicate of this one:
Access denied in IE 10 and 11 when ajax target is localhost
I need to expose better error detail from requireJS "load timeout for modules" errors so I can actually debug to find out what is causing the load timeout.
I'm unable to get the error to appear on my development machine, but roughly 10% of our daily visitors are experiencing this error in the production environment (track.js is being used to gather these errors for visibility).
The error is being thrown for my main.js file ("load timeout for modules: main") - the application entry point. I've added the errback callback to try to log the error detail here but this error doesn't seem to hit this callback so it seems as though everything main.js is requiring is fine.
I've added a global override for requirejs.onError and all I get here is the module name (main.js) and an error code of timeout.
I've used madge and have verified that there are no circular dependencies.
I have optimized the build using r.js optimizer.
I have set waitSeconds: 0 in require config (by my understanding should disable the timeout completely)
How can I find out what module that is being required somewhere down the line is actually causing the timeout? Anything further to go on would be very helpful - I'm finding this incredibly hard to track down. Thanks.
you can set waitSeconds in config of requireJS. By default it's 7 seconds. I do not know the exact answer to your question but this can be a temporary solution. Probably someone from users has a very slow internet. and it is not enough 7 seconds.
You can test in in Chrome devTools -> Network tab -> Throtling selector. And select for example "2G regular 450 kb/c". I assume that you will see this error. Also, this error sometimes occurred when I used CDN.
from James Burke himself. .....However if the difficulty is that your "main" is taking a long time to load, that script holds the requirejs.config() call with waitSeconds, and it was loaded via data-main, then the requirejs.config() call may not be called in time for it to be useful. For that issue, you can pass waitSeconds using "requirejs as initial config".
<script>var requirejs = { waitSeconds: 0 };</script>
<script src="require.js" data-main="main"></script>
This worked perfectly.
I am using QUnit to perform various simple tests on my website. One of the tests is creating a dialog, showing it and then closing it. The test runs fine, but when run on Firefox with Firebug activated I get an error:
3. Introduced global variable(s): _firebug
I can live with it, but it is annoying: the same code on Chrome runs fine. I ruled out jQuery UI as the culprit since the same error appears without it. However, running without Firebug or without console.log traces does not show the problem.
I grepped all the javascript code I am using and found no mention of any "firebug" variables; and Google was silent on the matter. I want my green screen (all tests passed) back! Any ideas?
After googling a little bit more, I am not the first to find this problem: badglobals.js, blog, Google groups. The solution to my particular problem (QUnit reports a leaky global variable) is to add the declaration of the global before starting the tests, for example before the first module is run:
var _firebug;
module('myModule');
I am seeing a spurious xdc variable too; same solution. My first QUnit test file now looks like this:
/* declare spurious Firebug globals */
var _firebug;
var _xdc_;
/* run tests */
module('myModule');
My bar is all green now, even with noglobals checked! I hope this helps anyone else who finds this annoying issue.