流星代码必须始终在节点流内的光纤错误中运行

时间:2015-01-29 08:41:36

标签: node.js meteor

我有这段代码:

Meteor.startup(function() {
    console.log("Starting IMAP");
    var Imap = Meteor.npmRequire('imap'),
        inspect = Meteor.npmRequire('util').inspect;

    var imap = new Imap({
        user: 'user@domain.com',
        password: 'xxx',
        host: 'imap.gmail.com',
        port: 993,
        tls: true
    });

    function findAttachmentParts(struct, attachments) {
        attachments = attachments ||  [];
        for (var i = 0, len = struct.length, r; i < len; ++i) {
            if (Array.isArray(struct[i])) {
                findAttachmentParts(struct[i], attachments);
            } else {
                if (struct[i].disposition && ['INLINE', 'ATTACHMENT'].indexOf(struct[i].disposition.type) > -1) {
                    attachments.push(struct[i]);
                }
            }
        }
        return attachments;
    }
    function buildAttMessageFunction(attachment) {
        var filename = attachment.params.name;
        var encoding = attachment.encoding;

        console.log("encoding: " + encoding);
        debugger;

    }
    function openInbox(cb) {
        imap.openBox('INBOX', true, cb);
    }

    imap.once('ready', function() {
        console.log("Imap is ready");
        openInbox(function(err, box) {
            if (err) throw err;
            //var f = imap.seq.fetch('1:30', {
            //bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
            //struct: true
            //});
            imap.search(['ALL',['SUBJECT', 'expertaerts']], function(err, results) {
                if (err) throw err;
                var f = imap.fetch(results, {
                    bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE BODY)'],
                    struct: true
                });
                f.on('message', function(msg, seqno) {
                    console.log('Message #%d', seqno);
                    var prefix = '(#' + seqno + ') ';
                    msg.on('body', function(stream, info) {
                        if (info.which === 'TEXT')
                            console.log(prefix + 'Body [%s] found, %d total bytes', inspect(info.which), info.size);
                        var buffer = '', count = 0;
                        stream.on('data', function(chunk) {
                            count += chunk.length;
                            buffer += chunk.toString('utf8');

                            console.log("BUFFER", buffer)

                        });
                        stream.once('end', function() {
                            console.log(prefix + 'Parsed header: %s', inspect(Imap.parseHeader(buffer)));
                            Meteor.call("createSharedocFDL", buffer.subject);
                        });
                    });
                    msg.once('end', function() {
                        console.log(prefix + 'Finished');
                    });
                });
                f.once('error', function(err) {
                    console.log('Fetch error: ' + err);
                });
                f.once('end', function() {
                    console.log('Done fetching all messages!');
                    imap.end();
                });
            });
        });
    });

    imap.once('error', function(err) {
        console.log(err);
    });

    imap.once('end', function() {
        console.log('Connection ended');
    });

    imap.connect();

});

它会生成以下错误消息:

W20150129-09:38:16.270(1)? (STDERR) Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
W20150129-09:38:16.270(1)? (STDERR)     at Object.Meteor._nodeCodeMustBeInFiber (packages/meteor/dynamics_nodejs.js:9:1)
W20150129-09:38:16.270(1)? (STDERR)     at [object Object]._.extend.get (packages/meteor/dynamics_nodejs.js:21:1)
W20150129-09:38:16.270(1)? (STDERR)     at [object Object]._.extend.apply (packages/ddp/livedata_server.js:1495:1)
W20150129-09:38:16.270(1)? (STDERR)     at [object Object]._.extend.call (packages/ddp/livedata_server.js:1455:1)
W20150129-09:38:16.270(1)? (STDERR)     at Readable.<anonymous> (app/server/imap.js:70:36)
W20150129-09:38:16.271(1)? (STDERR)     at Readable.g (events.js:180:16)
W20150129-09:38:16.271(1)? (STDERR)     at Readable.emit (events.js:92:17)
W20150129-09:38:16.271(1)? (STDERR)     at _stream_readable.js:943:16
W20150129-09:38:16.271(1)? (STDERR)     at process._tickCallback (node.js:419:13)

我该如何解决?

1 个答案:

答案 0 :(得分:0)

这是我最终解决它的方式:

stream.once('end', function() {
    console.log("Priour entering fiber");
    Fiber(function(){
         console.log("entering fiber");
         console.log(prefix + 'Parsed header: %s', inspect(Imap.parseHeader(buffer)));
         Meteor.call("createSharedocFDL", buffer.subject);
    }).run();
});

光纤内部的代码永远不会执行:

I20150130-07:20:33.246(1)? Priour entering fiber
I20150130-07:20:33.246(1)? (#151) Finished
I20150130-07:20:33.248(1)? Done fetching all messages!
I20150130-07:20:33.496(1)? { [Error: read ECONNRESET]
I20150130-07:20:33.496(1)?   code: 'ECONNRESET',
I20150130-07:20:33.496(1)?   errno: 'ECONNRESET',
I20150130-07:20:33.496(1)?   syscall: 'read',
I20150130-07:20:33.496(1)?   source: 'socket' }

我更愿意遵循@imslavko的建议并使用bindEnvironment,但是当我尝试使用它时,它仍然需要光纤。

在我看来,这种纤维的东西不是流星的方式。流星应该很容易使用。这一切都很简单。