Compacting account with unrefreshed junk folder via WebExtension Experiment API throws "undefined" error
Categories
(Thunderbird :: Add-Ons: Extensions API, defect)
Tracking
(Not tracked)
People
(Reporter: xpungetb, Unassigned)
References
Details
Attachments
(4 files)
Steps to reproduce:
Calling "nsIMsgFolder.compactAll" on an IMAP account with a junk folder that has not been refreshed in the TB folder pane view, returns an "undefined" error.
The actual code can be seen on GitHub here: https://github.com/theodore-tegos/xpunge-tb/blob/6d91937fbbfbbf2358e19c909f5ffd936ecbbb04/api/Xpunge/implementation.js#L157C1-L162C1
Using TB 140.0.1 on Ubuntu Linux 24.04.2 LTS 64-bit, I can reproduce 100% of the times by following the steps below. I also checked and the bug exists on the beta (141.0b4) and the nightly (142.0a1 (2025-07-17)).
Steps to reproduce:
-
Create a new TB profile
-
Add an IMAP Gmail account
-
Tick "Show Total Message Count" and "Show Folder Size" via the three dots menu on the folder pane
-
Let TB download all the messages, if you want to avoid potential interference with the empty/compact operations
-
Install the Xpunge extension, version 5.0.2 (needs to be made compatible with TB 140+)
-
Go to the Xpunge options page and set up MultiXpunge to empty only the Junk of the IMAP account and to compact only the whole IMAP account. So under the "MultiXpunge" tab, in the "Selected Trash Cans And Junk Folders To Be Emptied:" section, tick the "Junk" checkbox for the IMAP account. And in the "Choose Folder To Compact:" section, select the top-level IMAP account and click the "Add Selected" button.
-
Go back to the main TB tab, click on the "Inbox" folder and drag+drop 1 unread email into the "Spam" folder (e.g. the default junk folder on a Gmail account). Do not click on the "Spam" folder, so TB does not get to refresh it in the view. So "Inbox" is still the selected folder in TB and the "Spam" folder has not been refreshed.
-
Click the "MultiXpunge" button, which should now be present on the TB toolbar
-
Check the Error Console for messages written by Xpunge
Actual results:
On the Error Console, emptying the Junk folder(s) appears to be successful, as indicated by the "WebExtensions: XPUNGE: Done" info line immediately after the "Emptying junk folder ( Spam ) for account: xpungetbtest@gmail.com" info line.
However, after the info line: "WebExtensions: XPUNGE: Compacting all folders for account: xpungetb@gmail.com", the following error line is logged: "WebExtensions: XPUNGE: Failed compacting all folders for account: xpungetbtest@gmail.com undefined".
Clicking on the "Spam" folder in TB shows that it has not been emptied or compacted, the email is still there. This can also be verified independently via the Gmail interface.
Once I clicked on the "Spam" folder in TB and it got properly refreshed in the view, and then pressed the the MultiXpunge button, the error did not occur anymore. And the "Spam" folder seemed to be emptied and compacted without issues.
Expected results:
The "Failed compacting all folders ..." error line should not be logged on the Error Console after the "WebExtensions: XPUNGE: Compacting all folders for account ..." info line.
An info line that says "WebExtensions: XPUNGE: Done" should be logged, which indicates successful compacting.
Clicking on the "Spam" folder in TB should show it as empty and compacted.
punge messages on the Error Console when there is no error.
Did I file the bug on the right place? Should it maybe be under "WebExtensions"?
The Junk folders are emptied also with an WebExtension Experiment API, specifically "nsIMsgFolder.deleteMessages".
The actual code an be seen on GitHub here: https://github.com/theodore-tegos/xpunge-tb/blob/720aa4db8574e7e7a3f418e260e38ca528be15ee/api/Xpunge/implementation.js#L33
Updated•4 months ago
|
Comment 4•4 months ago
|
||
(In reply to Theodore from comment #3)
The Junk folders are emptied also with an WebExtension Experiment API, specifically "nsIMsgFolder.deleteMessages".
The actual code an be seen on GitHub here: https://github.com/theodore-tegos/xpunge-tb/blob/720aa4db8574e7e7a3f418e260e38ca528be15ee/api/Xpunge/implementation.js#L33
Taking a quick peek at that code, it looks like the UrlListener is absorbing the error code, so when the exception is caught, it's undefined.
https://github.com/theodore-tegos/xpunge-tb/blob/6d91937fbbfbbf2358e19c909f5ffd936ecbbb04/api/Xpunge/implementation.js#L14
I'm a little hazy on promises/async exception handling, but I think the reject() call should pass out the error code?
Doesn't change the fact that there's an error occurring during compaction, of course :-) We just can't tell what the error is.
It'd be interesting to see what the logging says, i.e. do a run with the environment var MOZ_LOG="compact:3" set (maybe also a filename via MOZ_LOG_FILE if you're not running with stdout/stderr going to a terminal window).
That would tell us what the underlying error code is (and which folder it's happening on).
Thanks Ben, I added the error code when UrlListener rejects:
console.info("XPUNGE: Debug UrlListener Failure:", exitCode);
this.PromiseWithResolvers.reject(exitCode);
The exit code is 2153054245:
21:21:56.638 WebExtensions: XPUNGE: Failed compacting all folders for account: xpungetbtest@gmail.com 2153054245 implementation.js:162
and the logs say:
[Parent 226665: Main Thread]: W/compact BatchCompactor::CanCompactNow(): HasOfflineActivity
[Parent 226665: Main Thread]: E/compact BatchCompactor - Can't compact
'imap://xpungetbtest%40gmail.com@imap.gmail.com/[Gmail]/Spam' now. Queued for retry.
I will upload the whole logs and Error Console in the "Attachments" section.
BTW, the tests in Comment #5 were done on TB 141.0.
Not related to this issue, but the folder pane in my TB renames the "Spam" folder to "Junk" , and junkFolder.prettyName on Line 90 returns "undefined" (as you can see from the Error Console messages in Comment #6).
Comment 9•4 months ago
|
||
(In reply to Theodore from comment #8)
BTW, the tests in Comment #5 were done on TB 141.0.
Not related to this issue, but the folder pane in my TB renames the "Spam" folder to "Junk" , and
junkFolder.prettyNameon Line 90 returns "undefined" (as you can see from the Error Console messages in Comment #6).
It is junkFolder.localizedName now. Please ask questions related to add-on updates/changes in the known add-on developer channels, as we should keep this bug focused on the core compacting issue.
Comment 10•2 months ago
|
||
is this bug still actively blocking Xpunge function/availability for TB, at least with 140.3.0esr ?
| Reporter | ||
Comment 11•1 month ago
|
||
(In reply to pgnd from comment #10)
is this bug still actively blocking Xpunge function/availability for TB, at least with 140.3.0esr ?
Yes, I just tested with TB 140.4.0esr and with TB 144.0, and the issue is still there in both.
Comment 12•27 days ago
|
||
(In reply to Theodore from comment #5)
Thanks Ben, I added the error code when
UrlListenerrejects:The exit code is
2153054245:
(quick aside... the error code names are now available via code, so the name should be available via the exception object and we shouldn't have to decode numeric errors like this. In this case, it's0x80550025, the0x8055means mail module, and 0x25 is decimal 37, which you can look up manually in errors.json
That's NS_MSG_ERROR_BLOCKED_COMPACTION - it means that a folder can't be compacted because it has pending IMAP operations. Most likely offline operations - eg a message was deleted while offline, and it's waiting until we're back online before performing the IMAP side of things.
In other words, there is some operation needs to be done to the server to bring it into sync with the client.
When compaction hits this, it'll retry a few times, with a 5 second pause in between. You can see this in the Comment 7 log:
...
[Parent 226665: Main Thread]: W/compact BatchCompactor::CanCompactNow(): HasOfflineActivity
[Parent 226665: Main Thread]: E/compact BatchCompactor - Can't compact 'imap://xpungetbtest%40gmail.com@imap.gmail.com/[Gmail]/Spam' now. Queued for retry.
[Parent 226665: Main Thread]: I/compact BatchCompactor: Attempt 1. Retrying 1 folders in 5000ms
...
So I'd think that either we're offline while this is happening (but I think you'd probably notice that, right?) or there's something in the IMAP offline-operations queue which isn't getting cleared for that spam folder...
In either case the compaction operation can't really do anything about it. The error is telling you that that one folder couldn't be compacted right now . But it has handled all the other folders.
Personally, I think the whole offline-operations support stuff is bonkers and brittle and bound to cause problems all over the place and I'd like like to remove it completely :-) Also I think that IMAP expunge and compaction should be disentangled (even if they appear as a unified command to the user). The entanglement causes all kinds of problems.
But those are longer-term, architectural projects.
For now, the workaround I'd recommend would be to check for NS_MSG_ERROR_BLOCKED_COMPACTION and treat it as a warning, with the meaning "try again later". Not ideal, I know.
Comment 13•24 days ago
•
|
||
With that feedback from Ben, I am going to close this bug as invalid. This is de facto a desired protection mechanism to prevent compacting while there are still pending operations.
Ben told me that a folder which still has pending operations has the Ci.nsMsgFolderFlags.OfflineEvents flag set.
You can use a onFolderIntPropertyChanged listener to be notified, when the flag is cleared. The reported property is FolderFlag and by looking at the provided values for oldValue and newValue you can learn, if the Ci.nsMsgFolderFlags.OfflineEvents flag was cleared:
// partially implements nsIFolderListener
var folderListener = {
onFolderIntPropertyChanged(item, property, oldValue, newValue) {
if (
property == "FolderFlag" &&
item instanceof Ci.nsIMsgFolder &&
(oldValue & Ci.nsMsgFolderFlags.OfflineEvents) &&
!(newValue & Ci.nsMsgFolderFlags.OfflineEvents)
) {
// flag was removed
// ...
}
}
}
MailServices.mailSession.AddFolderListener(
folderListener,
Ci.nsIFolderListener.intPropertyChanged
);
You can also just skip compaction and try again when it’s requested again.
Comment 14•15 days ago
|
||
@Theodore Do you think you can implement such a listener to repeat the compaction at a later time?
Is there any chance to get Xpunge back after 4 months?
Description
•