Error: The page has been destroyed and can no longer be used.

I am developing an add-in for the first time. It places a small widget in the status bar, which displays the number of unread Google Reader items. To take this into account, the add process requests the Google Reader API every minute and sends a response to the widget. When I run cfx test, I get this error:

Error: The page has been destroyed and can no longer be used.

I made sure I caught the event detachand stopped the update timer in response, but I still see the error. What am I doing wrong? Here is the relevant code:

// main.js - Main entry point
const tabs = require('tabs');
const widgets = require('widget');
const data = require('self').data;
const timers = require("timers");
const Request = require("request").Request;

function refreshUnreadCount() {
    // Put in Google Reader API request
    Request({
        url: "https://www.google.com/reader/api/0/unread-count?output=json",
        onComplete: function(response) {
            // Ignore response if we encountered a 404 (e.g. user isn't logged in)
            // or a different HTTP error.
            // TODO: Can I make this work when third-party cookies are disabled?
            if (response.status == 200) {
                monitorWidget.postMessage(response.json);
            } else {
                monitorWidget.postMessage(null);
            }
        }
    }).get();
}

var monitorWidget = widgets.Widget({
    // Mandatory widget ID string
    id: "greader-monitor",

    // A required string description of the widget used for
    // accessibility, title bars, and error reporting.
    label: "GReader Monitor",
    contentURL: data.url("widget.html"),
    contentScriptFile: [data.url("jquery-1.7.2.min.js"), data.url("widget.js")],

    onClick: function() {
        // Open Google Reader when the widget is clicked.
        tabs.open("https://www.google.com/reader/view/");
    },

    onAttach: function(worker) {
        // If the widget inner width changes, reflect that in the GUI
        worker.port.on("widthReported", function(newWidth) {
            worker.width = newWidth;
        });

        var refreshTimer = timers.setInterval(refreshUnreadCount, 60000);

        // If the monitor widget is destroyed, make sure the timer gets cancelled.
        worker.on("detach", function() {
            timers.clearInterval(refreshTimer);
        });

        refreshUnreadCount();
    }
});

// widget.js - Status bar widget script

// Every so often, we'll receive the updated item feed. It our job
// to parse it.
self.on("message", function(json) {
    if (json == null) {
        $("span#counter").attr("class", "");
        $("span#counter").text("N/A");
    } else {
        var newTotal = 0;
        for (var item in json.unreadcounts) {
            newTotal += json.unreadcounts[item].count;
        }

        // Since the cumulative reading list count is a separate part of the
        // unread count info, we have to divide the total by 2.
        newTotal /= 2;
        $("span#counter").text(newTotal);

        // Update style
        if (newTotal > 0)
            $("span#counter").attr("class", "newitems");
        else
            $("span#counter").attr("class", "");
    }

    // Reports the current width of the widget
    self.port.emit("widthReported", $("div#widget").width());
});

Change . I uploaded the entire project to this GitHub repository .

+5
3

, monitorWidget.port.emit("widthReported", response.json);, . script script.

0

, , monitorWidget.postMessage() refreshUnreadCount(). : refreshUnreadCount() , , , . .

refreshUnreadCount(). detach ( , ) , .

function refreshUnreadCount(worker) {
    var detached = false;
    function onDetach()
    {
        detached = true;
    }
    worker.on("detach", onDetach);

    Request({
        ...
        onComplete: function(response) {
            worker.removeListener("detach", onDetach);
            if (detached)
                return;  // Nothing to update with out data

            ...
        }
    }).get();
}

, try..catch , , - .

0

irc, . ​​SDK. .

, , .. widget.postMessage ( worker.postMessage). , , !

Then I suggest you move setInterval to the upper level, otherwise you will run several intervals and queries, one per window. This event is attachfired for every new firefox window.

0
source

All Articles