[WO-804] Fix bug where message cannot be parsed when deleted from IMAP

This commit is contained in:
Felix Hammerl 2015-02-13 17:10:44 +01:00 committed by Tankred Hase
parent 0faa5b3743
commit 54d495d8d9
2 changed files with 145 additions and 7 deletions

View File

@ -609,12 +609,15 @@ Email.prototype.getBody = function(options) {
folder: folder, folder: folder,
uid: message.uid uid: message.uid
}).then(function(localMessages) { }).then(function(localMessages) {
if (localMessages.length === 0) {
return;
}
localMessage = localMessages[0]; localMessage = localMessages[0];
if (!localMessage) {
// the message has been deleted in the meantime
var error = new Error('Can not get the contents of this message. It has already been deleted!');
error.hide = true;
throw error;
}
// treat attachment and non-attachment body parts separately: // treat attachment and non-attachment body parts separately:
// we need to fetch the content for non-attachment body parts (encrypted, signed, text, html, resources referenced from the html) // we need to fetch the content for non-attachment body parts (encrypted, signed, text, html, resources referenced from the html)
// but we spare the effort and fetch attachment content later upon explicit user request. // but we spare the effort and fetch attachment content later upon explicit user request.
@ -730,6 +733,10 @@ Email.prototype.getBody = function(options) {
}).catch(function(err) { }).catch(function(err) {
self.done(); self.done();
message.loadingBody = false; message.loadingBody = false;
if (err.hide) {
// ignore errors with err.hide
return message;
}
throw err; throw err;
}); });
@ -1558,6 +1565,14 @@ Email.prototype._getBodyParts = function(options) {
options.path = options.folder.path; options.path = options.folder.path;
return self._imapClient.getBodyParts(options); return self._imapClient.getBodyParts(options);
}).then(function() { }).then(function() {
if (options.bodyParts.filter(function(bodyPart) {
return !(bodyPart.raw || bodyPart.content);
}).length) {
var error = new Error('Can not get the contents of this message. It has already been deleted!');
error.hide = true;
throw error;
}
return self._parse(options); return self._parse(options);
}); });
}; };

View File

@ -1250,6 +1250,80 @@ describe('Email DAO unit tests', function() {
expect(message.loadingBody).to.be.true; expect(message.loadingBody).to.be.true;
}); });
it('should not error when message is deleted from imap', function(done) {
var error = new Error('Can not get the contents of this message. It has already been deleted!');
error.hide = true;
var message = {
uid: uid,
encrypted: true,
bodyParts: [{
type: 'text'
}]
};
localListStub.withArgs({
folder: inboxFolder,
uid: uid
}).returns(resolves([message]));
localStoreStub.withArgs({
folder: inboxFolder,
emails: [message]
}).returns(resolves());
imapGetStub.withArgs({
folder: inboxFolder,
uid: message.uid,
bodyParts: message.bodyParts
}).returns(rejects(error));
dao.getBody({
message: message,
folder: inboxFolder
}).then(function(msg) {
expect(msg).to.equal(message);
expect(msg.body).to.not.exist;
expect(msg.loadingBody).to.be.false;
expect(localListStub.calledOnce).to.be.true;
expect(imapGetStub.calledOnce).to.be.true;
expect(localStoreStub.called).to.be.false;
done();
});
expect(message.loadingBody).to.be.true;
});
it('should not error when message has already been removed from memory', function(done) {
var message = {
uid: uid,
encrypted: true,
bodyParts: [{
type: 'text'
}]
};
localListStub.returns(resolves([]));
dao.getBody({
message: message,
folder: inboxFolder
}).then(function(msg) {
expect(msg).to.equal(message);
expect(msg.body).to.not.exist;
expect(msg.loadingBody).to.be.false;
expect(localListStub.calledOnce).to.be.true;
expect(imapGetStub.called).to.be.false;
expect(localStoreStub.called).to.be.false;
done();
});
expect(message.loadingBody).to.be.true;
});
it('fail to stream from imap due to error when persisting', function(done) { it('fail to stream from imap due to error when persisting', function(done) {
var message = { var message = {
uid: uid, uid: uid,
@ -2393,18 +2467,23 @@ describe('Email DAO unit tests', function() {
describe('#_getBodyParts', function() { describe('#_getBodyParts', function() {
it('should get bodyParts', function(done) { it('should get bodyParts', function(done) {
var bp = [{
type: 'text',
content: 'bender is great! bender is great!'
}];
imapClientStub.getBodyParts.withArgs({ imapClientStub.getBodyParts.withArgs({
folder: inboxFolder, folder: inboxFolder,
path: inboxFolder.path, path: inboxFolder.path,
uid: 123, uid: 123,
bodyParts: [] bodyParts: bp
}).returns(resolves({})); }).returns(resolves(bp));
parseStub.yieldsAsync(null, []); parseStub.yieldsAsync(null, []);
dao._getBodyParts({ dao._getBodyParts({
folder: inboxFolder, folder: inboxFolder,
uid: 123, uid: 123,
bodyParts: [] bodyParts: bp
}).then(function(parts) { }).then(function(parts) {
expect(parts).to.exist; expect(parts).to.exist;
@ -2415,6 +2494,50 @@ describe('Email DAO unit tests', function() {
}); });
}); });
it('should fail when deleted on IMAP', function(done) {
var bp = [{
type: 'text'
}];
imapClientStub.getBodyParts.withArgs({
folder: inboxFolder,
path: inboxFolder.path,
uid: 123,
bodyParts: bp
}).returns(resolves());
parseStub.yieldsAsync(null, []);
dao._getBodyParts({
folder: inboxFolder,
uid: 123,
bodyParts: bp
}).catch(function(err) {
expect(err).to.exist;
expect(imapClientStub.getBodyParts.calledOnce).to.be.true;
expect(parseStub.called).to.be.false;
done();
});
});
it('should fail when getBody fails', function(done) {
imapClientStub.getBodyParts.returns(rejects({}));
dao._getBodyParts({
folder: inboxFolder,
uid: 123,
bodyParts: []
}).catch(function(err) {
expect(err).to.exist;
expect(imapClientStub.getBodyParts.calledOnce).to.be.true;
expect(parseStub.called).to.be.false;
done();
});
});
it('should fail when getBody fails', function(done) { it('should fail when getBody fails', function(done) {
imapClientStub.getBodyParts.returns(rejects({})); imapClientStub.getBodyParts.returns(rejects({}));