Search code examples
node.jsgcloud-node

Not found error in bucket.createReadStream


I just started using gcloud-node in an ExpressJS web app and have run in to what seems to be a very basic issue but I can't figure it out.

I can upload files no problem. I use:

fs.createReadStream(req.files.file.path)
    .pipe(bucket.createWriteStream(name))

Looking in my google developer console I see the file there in my bucket, for example with a name: 54314eddacd67fc858bf473f/543ba7bb387b56b908f2b1e4.jpg

When I try to download using that name i.e.:

bucket.createReadStream(file.name)
            .pipe(res)
             .on('error', function(err) {
                    errorResponseHandler.handleError(res, err);
                });

I get this error:

uncaughtException: Not Found Error: Not Found at Object.handleResp (/Users/ruairiobrien/Dev/testApp/node_modules/gcloud/lib/common/util.js:168:14) at Bucket.makeReq_ (/Users/ruairiobrien/Dev/testApp/node_modules/gcloud/lib/storage/index.js:580:10) at Request.Connection.req [as _callback] (/Users/ruairiobrien/Dev/testApp/node_modules/gcloud/lib/common/connection.js:251:16) at Request.init.self.callback (/Users/ruairiobrien/Dev/testApp/node_modules/gcloud/node_modules/request/request.js:199:22) at Request.emit (events.js:98:17) at Request.onResponse (/Users/ruairiobrien/Dev/testApp/node_modules/gcloud/node_modules/request/request.js:1160:14) at Request.emit (events.js:117:20) at IncomingMessage.Request.onResponse.strings (/Users/ruairiobrien/Dev/testApp/node_modules/gcloud/node_modules/request/request.js:1111:12) at IncomingMessage.emit (events.js:117:20) at _stream_readable.js:929:16 I have debugged through and I am certain that the file with the correct name exists in the bucket.

I'm really stumped on this so any help would be greatly appreciated.

I have tried writing the file to my local file system also rather than in the response and got the same error.

A temporary (or permanent) workaround that is working is this:

bucket.getSignedUrl({
                action: 'read',
                expires: Math.round(Date.now() / 1000) + (60 * 60 * 24), // 1 day.
                resource: file.name
            }, function (err, url) {
                res.redirect(url);

            });

The workaround works fine but doesn't help me figure out why the createReadStream fails since it shows that the file name and bucket are correct.


Solution

  • I think you might be using an outdated version of gcloud-node. Here's how I would do an upload and a download with the latest version (as of today, this is v0.14.0).

    var fs = require('fs');
    var gcloud = require('gcloud');
    
    var project = gcloud({
      projectId: 'your-project-id',
      // keyFilename: '/path/to/your/keyfile.json'
    });
    
    var bucket = project.storage().bucket('your-bucket-name');
    
    var filename = 'local-file-name';
    var file = bucket.file(filename); // This is a gcloud.File
    
    var getFiles = function() {
      bucket.getFiles(function(err, files) {
        console.log('Files were', files);
      });
    };
    
    var createFile = function() {
      fs.createReadStream(filename)
        .pipe(file.createWriteStream())
        .on('error', function (err) {
          console.log('Error!', err);
        })
        .on('complete', function(result) {
          console.log('Complete!', result);
        });
    };
    
    var getFile = function() {
      file.createReadStream()
        .pipe(fs.createWriteStream(filename + '.downloaded'))
        .on('error', function(err) {
          console.log('Error downloading!', err);
        });
    }
    
    createFile();
    getFile();
    

    Running this script should upload a file (local-file-name) on your bucket (your-bucket-name) and then download that file back as local-file-name.download).

    Some references to read through (there should be examples on each of these pages):