postalsys / imapflow

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

When trying to fetch source imapflow hangs. #230

Closed enyo closed 2 days ago

enyo commented 2 days ago

Whether I do this:

let messages = client.fetch(`1:*`, {
  source: true,
})
for await (let message of messages) {
  // Never reached
}

or, fetching the uids first and then do individual fetchOne like this:

let messages = await client.fetchOne(uid, {
  source: true,
}, { uid: true })
// Never reached

imapflow always just hangs there, and it is never resolved. If I remove the source attribute and just fetch envelope for example it works.

Do you have a tip of what that could be? I'm using Apple Mail email provider.

enyo commented 2 days ago

It also hangs if I try to use download

andris9 commented 2 days ago

You end up in an async generator deadloop. It can not continue because the previous action is not completed. The most common mistake with it is to use an IMAP call inside the async for loop. IMAP only works serially and if you try to do anything inside the loop, it can’t continue becuase the loop generator is still processing. And the loop can not continue because you are waiting for the IMAP response inside the loop.

enyo commented 2 days ago

Thanks for the swift response @andris9 but I'm pretty sure that's not the case since just removing source: true from the config works fine. I have added a source: {maxLength: 20} to test, and that works (but the message is cut off of course). I'm starting to suspect that it's due to me using Deno, and the TCP Stream implementations of Deno are not fully compatible with the node ones?...

andris9 commented 2 days ago

Oh, that explains. Deno and Bun are not supported. It might work but probably does not. As soon as you get into more complex TCP and TLs wrangling the differences between different runtimes raise to the ground.

andris9 commented 2 days ago

I guess what happens in your case is that when the data responded to the FETCH exceeds stream buffer size it breaks the async generator and ends up in a deadlock (second chunk is never read from the TCP socket). This would explain why smalles responses go through.

enyo commented 2 days ago

Yes that's exactly what happened. I just switched to node now and it works fine.