Parts of extension only work when BG DevTools is open

60 views
Skip to first unread message

Keith D Commiskey

unread,
Jul 15, 2020, 9:48:55 PM7/15/20
to Chromium Extensions
Shot in the dark here, but has anyone ever had any issues in which things only worked when the Background Page DevTools was open? 

I'm still isolating and trying to find a pattern to my issues, and although they would appear intermittent, nothing ever seems to happen so long as the Background Page DevTools are open. 

Could there perhaps be a race issue, but with DevTools being open it causes the browser to have a slight bit more to do while it's also working on the extension's code? E.g. having DevTools open yielding a larger asynchronous reentry queue, giving my extension's code a few K more microseconds to do its thing? 

Is this a known thing---or completely unheard of like most other things I come across? :-) (It could also be something in my code giving it the appearance of the BG being open being the culprit.)

How might you debug without DevTools being open?

P.S. I tried a search for this, but having only generic keywords such as "only works with background DevTools open" wasn't too helpful (or more likely I'm getting worse at searches :D ). Or maybe Stack Overflow would be a more appropriate place to ask this?

TIA -Keith

Keith D Commiskey

unread,
Jul 16, 2020, 2:25:43 AM7/16/20
to Chromium Extensions, Keith D Commiskey
Just FYI I found and fixed my primary issue(s), although I have absolutely no idea why it doesn't work as expected when the Background Page DevTools is open.

Apologies for any formatting nuances within this post; I don't post to these groups often. I also left out links/references to my extension and tried to keep these solution descriptions more generic in nature.

In any case, a quick overview for context: My extension will alert you when you're on a website for a set amount of time. The issue was when the browser resumed focus (from another app), a page's timer would reset, instead of continuing. But! This never happened when the Background Page DevTools were open.

Knowing I couldn't break it with BG DevTools open, I troubleshot the primary issue by:
  • In the background script, I did a `console.log` of just before where the issue occurs in the code (before the `confirm` dialog), and then turned on all my other `console logs` I have setup for debugging (key entry/exit points). 
  • I then opened the BG DevTools (knowing it was going to work) and watched for where it went after that particular console.log. 
  • I found it was going into the `onFocusChanged` listener. 
  • In there, I had removed a little _magic_ I didn't think applied for the longest time (b/c I keep DevTools near-always open), but now understand why it does.
## Broken and Fixed Code:
```
  // Changing Application Windows
  //

  inFocus = true;

  chrome.windows.onFocusChanged.addListener( function(window) {
    if (window == chrome.windows.WINDOW_ID_NONE) {
      inFocus = false; // Chrome does not have focus
    } else {

      // Works (Fix #1)
      if (inFocus) {   // _Magic_ Solution to not resetting the timer when the same tab is refocused !!!
        checkAndSetTimer('windows.onFocusChanged inside Else > IF -> inFocus');
      }

      // A while back I had removed the `if` block above and just directly ran `checkAndSetTimer()`.
      // I did this because, (with the DevTools always open,) it didn't appear it was necessary.

      // Broken
      // checkAndSetTimer('windows.onFocusChanged inside Else');

      inFocus = true;
    }
```
And! I realized a half hour later, because the `confirm` dialog box also receives focus briefly when one of its two buttons are clicked, another `inFocus = false` helped to solve an issue with the timer being reset on a new tab/page load.

## Additional Fixed Code:
```
  chrome.alarms.onAlarm.addListener(function(alarm) {
    if (confirm('Move on [Ok] or Continue [Cancel]')) {
      // ...
    } else {

      inFocus = false; // Sprinkled in a little more _magic_ here (Fix #2)

      chrome.browserAction.getBadgeText({}, function(result) { /* ... */ }
```

In doing all this, however, I still have no idea why the BG DevTools being open or closed has any effect on this. But the fixes work. :-)

## Steps to Create

Config: Inside my extension's popup, I setup a URL to be timed as 'google.com' with a one minute delay.
  1. Open browser Extensions page.
  2. Load/reload extension (if not already).
  3. Bring up the page to be timed (set in extension; e.g. google.com).
        > That will start the timer.
  4. Switch to your favorite text editor (or any non-browser app).
  5. Let the one minute expire, and the `confirm` dialog box will appear.
        > Side note: When the confirm dialog is open, although previously changed, the badge color changes back to its default color.
  6. Click 'Cancel' to stay on the site.
        > Focus will shift back to your favorite text editor.
        > You will see the badge text counter increase.
  7. Switch back to the browser window with google.com.
With BG DevTools open, or 'closed with the fix in place':
  • > The timer will stay at the current count
With BG DevTools closed (and no 'if(inFocus){}' logic in place):
  • > The timer will reset to "o_o".
## Steps to Create - New Tab/Page Load

For the steps above, #3 was an existing/already open tab. A new page load of a timed page would suffer the same issue, but only the very first time through. The second `inFocus = false` patch fixed that.

Not expecting much of this to make sense to anyone, but figured an explanation on my findings was due. And I'll sleep a little better tonight. :-)

-Keith

wOxxOm

unread,
Jul 16, 2020, 10:06:38 AM7/16/20
to Chromium Extensions, keith.c...@gmail.com
The usual reason is having "persistent":false in manifest.json declaration of the background script and writing the code as though the global state/variables is persisting, see the documentation.

Keith D Commiskey

unread,
Jul 16, 2020, 3:37:37 PM7/16/20
to Chromium Extensions, wOxxOm, Keith D Commiskey
Thank you for the feedback. This is interesting. Setting persistence to true fixes the issue, but wrapping my method call in a variable check condition also fixes it with persistence being set to false (which is what is instructed in the docs).

  if (inFocus) { // This fixes the issue, with persistence set to false
    checkAndSetTimer('windows.onFocusChanged inside Else > If -> inFocus');
  }

This being only my third extension, I came into it with the understanding from the docs, "'persistent' should be specified as false."

I delved into that further in my first two extensions, but always came around to more docs,
  • The only occasion to keep a background script persistently active is if the extension uses chrome.webRequest API to block or modify network requests. The webRequest API is incompatible with non-persistent background pages.
  • | If an extension currently uses a persistent background page, refer to Background Migration Guide for instruction on how to switch to a non-persistent model.
So, per the docs, I've always steered clear of the persistence setting. Unless webRequest is a general term covering what I'm using (chrome.windows or chrome.windows.onFocusChanged), I'm not sure I'm doing anything with network requests (but then unfortunately I lean more towards Front-end than DevOps). 

The interesting thing, however, is how can an `if` block achieve the same result as setting persistence to true? 
  • Is it somehow preventing the `inFocus` variable from being GCd? 
  • Or maybe it's not, and for other underlying technical reasons the `if` block is really just a band-aid which can also fail under other circumstances I haven't considered (for instance I haven't tested with a 40+ minute timer delay). 
  • Or maybe this is one of those exceptions where I would want persistence set to true? In light of the documentation though, I'm hoping the `if` block is a good enough solution to my issue (notwithstanding any hidden caveats).
This is all mostly still a couple levels over my head, but thank you again though for the input. > Forever learning. -Keith

Keith D Commiskey

unread,
Jul 16, 2020, 4:21:01 PM7/16/20
to Chromium Extensions, Keith D Commiskey, wOxxOm
I found another test case, so the `if` block was indeed just a band-aid. As you mentioned, I will check into how I can persist my background variables and see if I can keep the persistence set to false. Glad I posted and thanks again for the direction---I do usually end up getting the point, eventually. :-) -k
Reply all
Reply to author
Forward
0 new messages