mscdex / node-imap

An IMAP client module for node.js.
MIT License
2.15k stars 380 forks source link

Type Error when fetching mails #591

Open delsner opened 7 years ago

delsner commented 7 years ago

Unfortunately, I'm getting a type error when I'm fetching boxes from my gmail imap:

Fetching

// config
this.imap['connTimeout'] = 30000;
this.imap['authTimeout'] = 30000;
this.imap['keepAlive'] = false;

// fetching
this.imap.seq.fetch('1:*', {
          bodies: '',
          struct: true,
          markSeen: false,
          extensions: ['X-GM-LABELS'],
          modifiers: {
            changedsince: this.options.currentUser.highestmodseq || '0'
          },
}

Error

[connection] Connected to host
<= '* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- APPENDLIMIT=35651584'
<= 'A1 OK x@gmail.com authenticated (Success)'
=> 'A2 NAMESPACE'
<= '* NAMESPACE (("" "/")) NIL NIL'
<= 'A2 OK Success'
=> 'A3 LIST "" ""'
<= '* LIST (\\Noselect) "/" "/"'
<= 'A3 OK Success'
=> 'IDLE IDLE'
<= '+ idling'
=> DONE
<= 'IDLE OK IDLE terminated (Success)'
=> 'A4 SELECT "INBOX" (CONDSTORE)'
<= '* FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen $NotPhishing $Phishing)'
<= '* OK [PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen $NotPhishing $Phishing \\*)] Flags permitted.'
<= '* OK [UIDVALIDITY 1] UIDs valid.'
<= '* 16 EXISTS'
<= '* 0 RECENT'
<= '* OK [UIDNEXT 164] Predicted next UID.'
<= '* OK [HIGHESTMODSEQ 26215]'
<= 'A4 OK [READ-WRITE] INBOX selected. (Success)'
=> 'IDLE IDLE'
<= '+ idling'
=> DONE
<= 'IDLE OK IDLE terminated (Success)'
=> 'A5 FETCH 1:* (X-GM-THRID X-GM-MSGID X-GM-LABELS MODSEQ UID FLAGS INTERNALDATE BODYSTRUCTURE X-GM-LABELS BODY.PEEK[]) (CHANGEDSINCE 26019)'
<= '* 3 FETCH (X-GM-THRID 1552072915674217519 X-GM-MSGID 1552072915674217519 X-GM-LABELS ("\\\\Important") X-GM-LABELS ("\\\\Important") UID 86 MODSEQ (26025) INTERNALDATE "26-Nov-2016 14:54:36 +0000" FLAGS (\\Seen) BODYSTRUCTURE ("TEXT" "PLAIN" ("CHARSET" "UTF-8") NIL NIL "7BIT" 424 9 NIL NIL NIL) BODY[] {2113}'
<= '* 3 FETCH (X-GM-THRID 1552072915674217519 X-GM-MSGID 1552072915674217519 X-GM-LABELS ("\\\\Important") X-GM-LABELS ("\\\\Important") UID 86 MODSEQ (26025) INTERNALDATE "26-Nov-2016 14:54:36 +0000" FLAGS (\\Seen) BODYSTRUCTURE ("TEXT" "PLAIN" ("CHARSET" "UTF-8") NIL NIL "7BIT" 424 9 NIL NIL NIL) )'
<= '* 12 FETCH (X-GM-THRID 1556136739025124575 X-GM-MSGID 1556136739025124575 X-GM-LABELS () X-GM-LABELS () UID 156 MODSEQ (26198) INTERNALDATE "10-Jan-2017 11:27:20 +0000" FLAGS (\\Seen) BODYSTRUCTURE (("TEXT" "PLAIN" ("CHARSET" "utf-8") NIL NIL "QUOTED-PRINTABLE" 597 18 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "utf-8") NIL NIL "QUOTED-PRINTABLE" 25238 636 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "----sinikael-?=_1-14840476404950.23768100250220492") NIL NIL) BODY[] {28263}'
<= '* 12 FETCH (X-GM-THRID 1556136739025124575 X-GM-MSGID 1556136739025124575 X-GM-LABELS () X-GM-LABELS () UID 156 MODSEQ (26198) INTERNALDATE "10-Jan-2017 11:27:20 +0000" FLAGS (\\Seen) BODYSTRUCTURE (("TEXT" "PLAIN" ("CHARSET" "utf-8") NIL NIL "QUOTED-PRINTABLE" 597 18 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "utf-8") NIL NIL "QUOTED-PRINTABLE" 25238 636 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "----sinikael-?=_1-14840476404950.23768100250220492") NIL NIL) )'
<= '* 16 FETCH (X-GM-THRID 1557336791911223481 X-GM-MSGID 1557336791911223481 X-GM-LABELS ("\\\\Important" "\\\\Sent") X-GM-LABELS ("\\\\Important" "\\\\Sent") UID 163 MODSEQ (26163) INTERNALDATE "23-Jan-2017 17:21:40 +0000" FLAGS () BODYSTRUCTURE ("TEXT" "PLAIN" NIL NIL NIL "7BIT" 0 0 NIL NIL NIL) BODY[] {622}'
<= '* 16 FETCH (X-GM-THRID 1557336791911223481 X-GM-MSGID 1557336791911223481 X-GM-LABELS ("\\\\Important" "\\\\Sent") X-GM-LABELS ("\\\\Important" "\\\\Sent") UID 163 MODSEQ (26163) INTERNALDATE "23-Jan-2017 17:21:40 +0000" FLAGS () BODYSTRUCTURE ("TEXT" "PLAIN" NIL NIL NIL "7BIT" 0 0 NIL NIL NIL) )'
<= 'A5 OK Success'
=> 'IDLE IDLE'
<= '+ idling'
TypeError: Cannot read property 'type' of undefined
    at Parser.<anonymous> (/Users/delsner/workspace/email-client/emailappserver/node_modules/imap/lib/Connection.js:226:28)
    at emitOne (events.js:96:13)
    at Parser.emit (events.js:188:7)
    at Parser._resContinue (/Users/delsner/workspace/email-client/emailappserver/node_modules/imap/lib/Parser.js:296:8)
    at Parser._parse (/Users/delsner/workspace/email-client/emailappserver/node_modules/imap/lib/Parser.js:141:16)
    at Parser._tryread (/Users/delsner/workspace/email-client/emailappserver/node_modules/imap/lib/Parser.js:82:15)
    at TLSSocket.Parser._cbReadable (/Users/delsner/workspace/email-client/emailappserver/node_modules/imap/lib/Parser.js:53:12)
    at emitNone (events.js:86:13)
    at TLSSocket.emit (events.js:185:7)
    at emitReadable_ (_stream_readable.js:438:10)
    at emitReadable (_stream_readable.js:432:7)
    at readableAddChunk (_stream_readable.js:183:13)
    at TLSSocket.Readable.push (_stream_readable.js:130:10)
    at TLSWrap.onread (net.js:542:20)
    at Socket.ondata (_stream_wrap.js:58:20)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:172:18)
    at Socket.Readable.push (_stream_readable.js:130:10)
    at TCP.onread (net.js:542:20)

The line 226 is var type = self._curReq.type; in the context:

parser.on('continue', function(info) {
    var type = self._curReq.type;
    if (type === 'IDLE') {
      if (self._queue.length
          && self._idle.started === 0
          && self._curReq
          && self._curReq.type === 'IDLE'
          && self._sock
          && self._sock.writable
          && !self._idle.enabled) {
        self.debug && self.debug('=> DONE');
        self._sock.write('DONE' + CRLF);
        return;
      }
      // now idling
      self._idle.started = Date.now();
    } else if (/^AUTHENTICATE XOAUTH/.test(self._curReq.fullcmd)) {
      self._curReq.oauthError = new Buffer(info.text, 'base64').toString('utf8');
      self.debug && self.debug('=> ' + inspect(CRLF));
      self._sock.write(CRLF);
    } else if (type === 'APPEND') {
      self._sockWriteAppendData(self._curReq.appendData);
    } else if (self._curReq.lines && self._curReq.lines.length) {
      var line = self._curReq.lines.shift() + '\r\n';
      self.debug && self.debug('=> ' + inspect(line));
      self._sock.write(line, 'binary');
    }
  });

I would appreciate any kind of help! Using version 0.8.19. Thank you.

slaupster commented 7 years ago

I've seen the same issue at Connection.js:1265

iby commented 5 years ago

@mscdex Any idea why this might be happening? Hitting exactly the same issue. It was floating around a few days ago, but then went away. I thought something have fixed it. Now seeing it again, happens with Outlook after the last log message:

console.log node_modules/imap/lib/Parser.js:132
    <= 'A3 OK LOGIN completed.'

  console.log node_modules/imap/lib/Connection.js:1737
    => 'A4 CAPABILITY'

  console.log node_modules/imap/lib/Parser.js:132
    <= '* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CLIENTACCESSRULES CLIENTNETWORKPRESENCELOCATION BACKENDAUTHENTICATE CHILDREN IDLE NAMESPACE LITERAL+'

  console.log node_modules/imap/lib/Parser.js:132
    <= 'A4 OK CAPABILITY completed.'

  console.log node_modules/imap/lib/Connection.js:1737
    => 'A5 NAMESPACE'

  console.log node_modules/imap/lib/Parser.js:132
    <= '* NAMESPACE (("" "/")) NIL NIL'

  console.log node_modules/imap/lib/Parser.js:132
    <= 'A5 OK NAMESPACE completed.'

  console.log node_modules/imap/lib/Connection.js:1737
    => 'A6 LIST "" ""'

  console.log node_modules/imap/lib/Parser.js:132
    <= '* LIST (\\Noselect \\HasChildren) "/" ""'

  console.log node_modules/imap/lib/Parser.js:132
    <= 'A6 OK LIST completed.'

  console.log node_modules/imap/lib/Connection.js:1737
    => 'IDLE IDLE'

  console.log node_modules/imap/lib/Connection.js:137
    [connection] Connected to host

  console.log node_modules/imap/lib/Parser.js:132
    <= '+ IDLE accepted, awaiting DONE command.'
tikidave commented 2 years ago
VM1001 Connection.js:227 Uncaught TypeError: Cannot read property 'type' of undefined
    at Parser.<anonymous> (VM1001 Connection.js:227)

This issue has been open for four years, why hasn't it been fixed?

As stated above the problem is there is no check for the existence of a _curReq here:

parser.on('continue', function(info) {
  var type = self._curReq.type;
Reda1000 commented 2 years ago

For me it appeared this issue arose when not wating on internal "LOGOUT" - which is signalled via 'end'-Event.

I was releasing the socket through imap.end() but did not wait for arrival of 'end'-Event already doing the next connect. After making sure imap.connect() runs always after 'end'-Event has fired:

I eventually ended up with something like this:

/* just a simple loop and lock / 'semaphore' */
let lock = false;
while(1) {
  if(lock) continue;

  lock = true;

  imap.once('ready', () => { 
    /*...*/ 
    imap.end() 
  })
  imap.once('end', () => { 
    /* IMPORTANT: unlock next run of connect not earlier than here */ 
    lock = false 
  });
  imap.connect();
}
imap.once('end', () => {...})