Uploading empty attachment file produces TypeError: Cannot read property 'resume' of undefined
tomanwalker opened this issue · comments
Please read these guidelines before opening an issue.
Bug Description
1. Steps to reproduce and the simplest code sample possible to demonstrate the issue
var Cloudant = require('@cloudant/cloudant');
var config = require('../config.js');
var con = new Cloudant({
url: config.cloudant_host,
plugins:{
iamauth:{
iamApiKey: config.cloudant_key
}
}
});
var myDB = con.use(config.MY_DB_NAME);
myDB.attachment.insert(docId, pictureId, pictureObj, contentType, { rev: doc._rev}, function(err, saved_doc) {
log.debug('uploadPicture done');
if (!err)
return resolve(saved_doc);
else{
log.debug('returning err');
error.message = err.message;
error.statusCode = "CLOUDANT_ERROR";
error.httpHeader = 503;
return error;
}
});
2. What you expected to happen
IAM-plugin to work
3. What actually happened
Random crashes, especially working with attachments.
January 8th 2019, 07:58:36.050 npm ERR! errno 1
January 8th 2019, 07:58:36.049 at updateState (/home/vcap/app/node_modules/@cloudant/cloudant/lib/clientutils.js:53:3)
January 8th 2019, 07:58:36.049 at IAMPlugin.onError (/home/vcap/app/node_modules/@cloudant/cloudant/plugins/base.js:50:5)
January 8th 2019, 07:58:36.049 at replenish (/home/vcap/app/node_modules/@cloudant/cloudant/node_modules/async/dist/async.js:1025:25)
January 8th 2019, 07:58:36.049 at iterateeCallback (/home/vcap/app/node_modules/@cloudant/cloudant/node_modules/async/dist/async.js:1015:17)
January 8th 2019, 07:58:36.049 at /home/vcap/app/node_modules/@cloudant/cloudant/lib/clientutils.js:137:11
January 8th 2019, 07:58:36.049 at /home/vcap/app/node_modules/@cloudant/cloudant/node_modules/async/dist/async.js:988:16
January 8th 2019, 07:58:36.048 at /home/vcap/app/node_modules/@cloudant/cloudant/node_modules/async/dist/async.js:484:16
January 8th 2019, 07:58:36.048 at /home/vcap/app/node_modules/@cloudant/cloudant/lib/clientutils.js:154:11
January 8th 2019, 07:58:36.048 at processState (/home/vcap/app/node_modules/@cloudant/cloudant/lib/clientutils.js:118:14)
January 8th 2019, 07:58:36.048 TypeError: Cannot read property 'resume' of undefined
January 8th 2019, 07:58:36.047 r.response.resume();
Environment details
I had no problem uploading an attachment in this way using IAM credentials.
Please complete the bug template's Environment details
so we can better debug the issue.
You said you expected the "IAM-plugin to work". Does that mean you only see these issues when using the iamauth
plugin, but specifically not when using other credentials?
@ricellis
Thanks for the reply)
Yeah, I couldn't collect more than Error stackTrace. The issue seem to appear randomly (once in a few days) - thus I might think it have smth to do with token refresh, but no sure.
you said you expected the "IAM-plugin to work
well, I can see in the stackTrace the exception is originated there, thus the claim
Ideally, can the library be patched to provide more insights about why "r.response" variable is undefined in @cloudant/cloudant/lib/clientutils.js:118:14 - I'd be happy then to provide output when the issue fires again.
If you can reproduce with the debug env vars:
DEBUG=cloudant*,nano
NODE_DEBUG=request
then there will probably be enough additional context to better detect the issue, but it will be very verbose and you'll probably want to check and redact anything sensitive before uploading anything as it will include HTTP headers etc.
I think tokens are valid for 60 minutes by default, so I'd be surprised if a refresh issue only showed up every few days.
Hi, I've got a way to reproduce the issue. Turns out it happens with an empty file.
@ricellis
Program
// ## config
var apikey = "***";
var host = "https://55faa453-1121-4832-a165-b499339d0e8e-bluemix.cloudant.com";
var dbname = "random-db";
var targetDoc = {
"_id": "0056318860f19ad9e5853179fb9602e4",
"_rev": "2-d7b79405b99b933fb76cc5d4ac4f9bc1"
};
// ## dependencies
var Cloudant = require('@cloudant/cloudant');
var fs = require('fs');
// ## flow
console.log('Before cloudant connection...');
var connection = new Cloudant({
url: host,
plugins:{
iamauth:{
iamApiKey: apikey
}
}
});
mydb = connection.use(dbname);
console.log('Before File read...');
var myFile = fs.readFileSync('testData/empty_file.txt'); // File is an empty text file
console.log('Before File insert...');
mydb.attachment.insert(targetDoc._id, 'testFile.txt', myFile, 'plain/txt', { rev: targetDoc._rev}, function(err, body) {
if(err){
console.log('err = %s', JSON.stringify(err));
}
else{
console.log('ok = %s', JSON.stringify(body));
}
});
Output
$ node ./couch_issue.js
Before cloudant connection...
Before File read...
Before File insert...
C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\lib\clientutils.js:118
r.response.resume();
^
TypeError: Cannot read property 'resume' of undefined
at processState (C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\lib\clientutils.js:118:14)
at C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\lib\clientutils.js:154:11
at C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\node_modules\async\dist\async.js:484:16
at replenish (C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\node_modules\async\dist\async.js:1025:25)
at iterateeCallback (C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\node_modules\async\dist\async.js:1015:17)
at C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\node_modules\async\dist\async.js:988:16
at updateState (C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\lib\clientutils.js:53:3)
at C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\lib\clientutils.js:137:11
at IAMPlugin.onError (C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\plugins\base.js:50:5)
at C:\DFL\Workbench\app\node_modules\@cloudant\cloudant\lib\clientutils.js:136:25
Thanks, we'll look into it.
We need to do a fix here to correctly propagate the underlying error instead of failing with the TypeError
.
The underlying error is Error: Argument error, options.body.
caused by request/request#920
There appears to be a PR open for that issue in request
so hopefully we can consume a fixed version in the not too distant future.
Thanks @smithsz for digging that up
Closing as it seems that the upstream PR is unlikely to ever get merged given that request
is deprecated.
In our new cloudant-node-sdk(beta) a zero length attachment uploads without error. There is an example of using putAttachment
in the docs.