Skip to content

value object of reqOpts object does not have hasOwnProperty method #2070

Description

@gajus

v0.48.0 of google-cloud package is resulting in an error when attempting to upload a file.

The following code is enough to reproduce the issue.

import createGcloud from 'google-cloud';

const credentials = JSON.parse(new Buffer(process.env.GOOGLE_CLOUD_CREDENTIALS, 'base64').toString());

const gcloud = createGcloud({
  credentials,
  projectId: argv.googleProjectId
});

const gcs = gcloud.storage();
const bucket = gcs.bucket(argv.googleStorageBucketName);

const posterFilePath = 'replace with a file path';

await bucket.upload(posterFilePath, {
  destination: 'posters/test.jpg',
  gzip: true,
  metadata: {
    contentLanguage: 'en',
    contentType: 'image/jpeg'
  },
  predefinedAcl: 'publicRead',
  resumable: false,
  validation: 'md5'
});

The error itself is misleading (see #2069):

Error: Sorry, we cannot connect to Cloud Services without a project ID. You may specify one with an environment variable named "GCLOUD_PROJECT". See https://googlecloudplatform.github.io/google-cloud-node/#/docs/guides/authentication for a detailed guide on creating an authenticated connection.
    at Object.<anonymous> (/Users/gajus/Documents/dev/applaudience/movie-editor/node_modules/google-cloud/node_modules/@google-cloud/common/src/util.js:55:29)
    at Module._compile (module.js:571:32)
    at Module._extensions..js (module.js:580:10)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/gajus/Documents/dev/applaudience/movie-editor/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/gajus/Documents/dev/applaudience/movie-editor/node_modules/google-cloud/node_modules/@google-cloud/common/src/service-object.js:32:12)

The real error originates here:

  if (is.object(value) && is.fn(value.hasOwnProperty)) {
    for (var opt in value) {
+      if (value.hasOwnProperty(opt)) {
        value[opt] = replaceProjectIdToken(value[opt], projectId);
      }
    }
  }

The value Object does not have hasOwnProperty method.

The reqOpts object looks like this:

{ method: 'POST',
  qs:
   { uploadType: 'multipart',
     name: 'posters/poster-1000216-2017-beauty-and-the-beast.jpg',
     predefinedAcl: 'publicRead' },
  uri: 'https://www.googleapis.com/upload/storage/v1/b/applaudience/o',
  multipart:
   [ { 'Content-Type': 'application/json',
       body: '{"contentLanguage":"en","contentType":"image/jpeg","metadata":{"applaudience-movie-id":1000216,"movie-release-year":"2017","movie-title":"Beauty and the Beast"},"contentEncoding":"gzip"}' },
     { 'Content-Type': 'image/jpeg', body: [Object] } ],
  headers:
   { 'User-Agent': 'gcloud-node-storage/0.7.0',
     Authorization: 'Bearer REDACTED' } }
value { end:
   [ { [Function: bound onceWrapper] listener: [Function: onend] },
     [Function: onend] ],
  prefinish: { [Function: bound onceWrapper] listener: [Function] },
  finish: [Function: onfinish],
  error: { [Function: f] called: false },
  close: [Function: onclose],
  drain: [Function: ondrain] }

Not very useful, but confirms that the former code sample is creating the error.

For whatever reason (I didn't dig that deep), the object contained in the value property does not have hasOwnProperty method. In case relevant, Node.js v7.7.1.

Activity

  1. stephenplusplus commented on Mar 9, 2017

    @stephenplusplus
    Contributor

    This is interesting, and the same issue as #2050. We (tried to) fix that by adding is.fn(value.hasOwnProperty) before attempting to call value.hasOwnProperty. The fix is in master, and released under @google-cloud/[email protected], but didn't make it into [email protected]. Can you try installing @google-cloud/storage and see if it was a satisfactory fix?

  2. gajus commented on Mar 9, 2017

    @gajus
    Author

    Just installing @google-cloud/common will do no good.

    Something like this should work, though:

    npm install @google-cloud/common
    rm -fr ./node_modules/google-cloud/node_modules/@google-cloud/common

    I can confirm that it fixes the problem.

    Is there a workaround in the mean time that doesn't require deleting files?

  3. stephenplusplus commented on Mar 9, 2017

    @stephenplusplus
    Contributor

    'google-cloud' is just a bundled package that includes all of the service APIs. So you can install just '@google-cloud/storage' and use it directly until the 'google-cloud' package is updated. Sorry you ran into this. I will try to put out a new release today.

  4. added
    api: storageIssues related to the Cloud Storage API.
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    on Mar 9, 2017
  5. abdulj commented on May 1, 2017

    @abdulj

    I am running in to this issue since yesterday. The code is in cloud functions trying to access cloud storage using "@google-cloud/storage": "1.1.0" .
    const Storage = require('@google-cloud/storage')();

    Error: Sorry, we cannot connect to Cloud Services without a project ID. You may specify one with an environment variable named "GCLOUD_PROJECT". See https://googlecloudplatform.github.io/google-cloud-node/#/docs/guides/authentication for a detailed guide on creating an authenticated connection.
    at Object. (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:55:29)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object. (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/service-object.js:32:12)
    at Module._compile (module.js:570:32)"

    The same cloud function also connects to datastore, which works without hitting this issue.

  6. stephenplusplus commented on May 1, 2017

    @stephenplusplus
    Contributor

    @abdulj are you running a specific method in the Storage API when you see the error?

  7. abdulj commented on May 1, 2017

    @abdulj

    @stephenplusplus I tried the below written two ways , both leading to this error.

    var file = bucket.file(name);
    file.save(content,options, (err) => {
      //custom code here
    });
    var file = bucket.file(name);
    str.pipe(file.createWriteStream(options))
      .on ('error',function(err) {
        // custom code removed
      })
      .on('finish',function() {
        // custom code removed
      });
  8. stephenplusplus commented on May 1, 2017

    @stephenplusplus
    Contributor

    @abdulj I've been trying and failing to reproduce. Could you try this isolated example and see that it still occurs? https://gist.github.com/stephenplusplus/adf3b2bf3a6df17d3178def4a31aba6c

  9. abdulj commented on May 1, 2017

    @abdulj

    @stephenplusplus thanks for the quick responses :) and sorry that I did not debug enough before commenting here.
    Looks like I was passing an object for filename instead of a string, this was entity key from datastore. I wanted the entity key (numeric ID) to be used as filename, and passed the key object as filename. Error was misleading though. Thanks again.

  10. stephenplusplus commented on May 1, 2017

    @stephenplusplus
    Contributor

    I'm glad it worked out! We have an issue to address the confusing error here: #2069 -- sorry for that :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

api: storageIssues related to the Cloud Storage API.coretype: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions