postalsys / imapflow

IMAP Client library for EmailEngine Email API (https://emailengine.app)
https://imapflow.com
Other
345 stars 58 forks source link

`fetch` with sequence string `1:*` seems to fail if mailbox is empty #209

Closed Remscar closed 1 week ago

Remscar commented 1 month ago

When using .fetch like this:

const inboxMessages = client.fetch("1:*", {
      uid: true,
      source: true,
      envelope: true,
      bodyParts: ["text"],
      bodyStructure: true,
    });

It works just fine if the mailbox has messages in it, but if there are no messages then an error is thrown.

With logging enabled i see this:

{"level":20,"time":1720587672327,"pid":162128,"hostname":"ICEBOX","component":"imap-connection","cid":"ocwf3bbytwuujaqasmuw","src":"s","msg":"8 FETCH 1:* (UID BODYSTRUCTURE ENVELOPE BODY.PEEK[] MODSEQ BODY.PEEK[TEXT])","cid":"ocwf3bbytwuujaqasmuw"}
{"level":20,"time":1720587672331,"pid":162128,"hostname":"ICEBOX","component":"imap-connection","cid":"ocwf3bbytwuujaqasmuw","src":"s","msg":"8 BAD Error in IMAP command FETCH: Invalid messageset (0.001 + 0.000 secs).","cid":"ocwf3bbytwuujaqasmuw"}
{"level":40,"time":1720587672332,"pid":162128,"hostname":"ICEBOX","component":"imap-connection","cid":"ocwf3bbytwuujaqasmuw","err":{"type":"Error","message":"Command failed","stack":"Error: Command failed\n    at ImapFlow.reader (xxxxxxxxx\\node_modules\\imapflow\\lib\\imap-flow.js:571:35)\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)","response":{"tag":"8","command":"BAD","attributes":[{"type":"TEXT","value":"Error in IMAP command FETCH: Invalid messageset (0.001 + 0.000 secs)."}]},"responseStatus":"BAD","responseText":"Error in IMAP command FETCH: Invalid messageset (0.001 + 0.000 secs)."},"cid":"ocwf3bbytwuujaqasmuw","msg":"Command failed"}

8 BAD Error in IMAP command FETCH: Invalid messageset (0.001 + 0.000 secs). seems important.

I know i could use .status to see if there are any messages, but is there another way around this?

gazhay commented 1 month ago

Just hit this error too. Using code extremely close to the example here

let mailbox = await client.mailboxOpen('INBOX');
// fetch UID for all messages in a mailbox
for await (let msg of client.fetch('1:*', {uid: true})){
    console.log(msg.uid);
    // NB! You can not run any IMAP commands in this loop
    // otherwise you will end up in a deadloop
}

This will crash with

Command failed

    at ImapFlow.reader (/app/node_modules/imapflow/lib/imap-flow.js:571:35)

    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {

  response: { tag: 'A', command: 'BAD', attributes: [ [Object] ] },

  responseStatus: 'BAD',

  responseText: 'Error in IMAP command FETCH: Invalid messageset (0.001 + 0.000 secs).'

Additionally, the for await is a PITA to handle errors correctly even if you try...catch the entire thing. (but that's a me problem)

benbucksch commented 1 month ago

This looks an error from the IMAP server. Nonetheless very inconvenient, indeed.

I ran into the same problem. I avoid fetch when the folder list says that the message count for this folder is 0.

But there are other edge cases when this happens, e.g. when deleting the last message in a folder.

andris9 commented 1 week ago

In general, this is a server issue. A server might respond with an empty response to such a query or respond with an error. If the message count for a mailbox is 0, then avoid making fetch queries.