Google Cloud Function - Error: ENOENT: no such file or directory










0















I'm trying to do a simple function that resizes a newly uploaded image in Storage. I use the following to help me do that:



import tmpdir from 'os';
import join, dirname from 'path';
import * as sharp from 'sharp';
import * as fs from 'fs-extra';


When this code executes:



await bucket.file(filePath).download(
destination: tmpFilePath
);


I get the following error in the Google Cloud Function logs:




Error: ENOENT: no such file or directory, open '/tmp/images/1542144115815_Emperor_penguins.jpg' at Error (native)




Here is the full code [segment]:



const gcs = admin.storage();
const db = admin.firestore();

import tmpdir from 'os';
import join, dirname from 'path';

import * as sharp from 'sharp';
import * as fs from 'fs-extra';

export const imageResize = functions.storage
.object()
.onFinalize(async object => {
console.log('> > > > > > > 1.3 < < < < < < <');
const bucket = gcs.bucket(object.bucket);
console.log(object.name);
const filePath = object.name;
const fileName = filePath.split('/').pop();
const tmpFilePath = join(tmpdir(), object.name);

const thumbFileName = 'thumb_' + fileName;
const tmpThumbPath = join(tmpdir(), thumbFileName);

console.log('step 1');
// Resizing image
if (fileName.includes('thumb_'))
console.log('exiting function');
return false;

console.log('step 2');
console.log(`filePath: $filePath`);
console.log(`tmpFilePath: $tmpFilePath`);
await bucket.file(filePath).download(
destination: tmpFilePath
);
console.log('step 3');
await sharp(tmpFilePath)
.resize(200, 200)
.toFile(tmpThumbPath);

await bucket.upload(tmpThumbPath,
destination: join(dirname(filePath), thumbFileName)
);


UPDATE 1: added await fs.ensureDir(tmpFilePath); to ensure the filepath exists. Now getting a new error:




Error: EINVAL: invalid argument, open '/tmp/images/1542146603970_mouse.png' at Error (native)




UPDATE 2 SOLVED: Added a solution as an Answer below.










share|improve this question




























    0















    I'm trying to do a simple function that resizes a newly uploaded image in Storage. I use the following to help me do that:



    import tmpdir from 'os';
    import join, dirname from 'path';
    import * as sharp from 'sharp';
    import * as fs from 'fs-extra';


    When this code executes:



    await bucket.file(filePath).download(
    destination: tmpFilePath
    );


    I get the following error in the Google Cloud Function logs:




    Error: ENOENT: no such file or directory, open '/tmp/images/1542144115815_Emperor_penguins.jpg' at Error (native)




    Here is the full code [segment]:



    const gcs = admin.storage();
    const db = admin.firestore();

    import tmpdir from 'os';
    import join, dirname from 'path';

    import * as sharp from 'sharp';
    import * as fs from 'fs-extra';

    export const imageResize = functions.storage
    .object()
    .onFinalize(async object => {
    console.log('> > > > > > > 1.3 < < < < < < <');
    const bucket = gcs.bucket(object.bucket);
    console.log(object.name);
    const filePath = object.name;
    const fileName = filePath.split('/').pop();
    const tmpFilePath = join(tmpdir(), object.name);

    const thumbFileName = 'thumb_' + fileName;
    const tmpThumbPath = join(tmpdir(), thumbFileName);

    console.log('step 1');
    // Resizing image
    if (fileName.includes('thumb_'))
    console.log('exiting function');
    return false;

    console.log('step 2');
    console.log(`filePath: $filePath`);
    console.log(`tmpFilePath: $tmpFilePath`);
    await bucket.file(filePath).download(
    destination: tmpFilePath
    );
    console.log('step 3');
    await sharp(tmpFilePath)
    .resize(200, 200)
    .toFile(tmpThumbPath);

    await bucket.upload(tmpThumbPath,
    destination: join(dirname(filePath), thumbFileName)
    );


    UPDATE 1: added await fs.ensureDir(tmpFilePath); to ensure the filepath exists. Now getting a new error:




    Error: EINVAL: invalid argument, open '/tmp/images/1542146603970_mouse.png' at Error (native)




    UPDATE 2 SOLVED: Added a solution as an Answer below.










    share|improve this question


























      0












      0








      0








      I'm trying to do a simple function that resizes a newly uploaded image in Storage. I use the following to help me do that:



      import tmpdir from 'os';
      import join, dirname from 'path';
      import * as sharp from 'sharp';
      import * as fs from 'fs-extra';


      When this code executes:



      await bucket.file(filePath).download(
      destination: tmpFilePath
      );


      I get the following error in the Google Cloud Function logs:




      Error: ENOENT: no such file or directory, open '/tmp/images/1542144115815_Emperor_penguins.jpg' at Error (native)




      Here is the full code [segment]:



      const gcs = admin.storage();
      const db = admin.firestore();

      import tmpdir from 'os';
      import join, dirname from 'path';

      import * as sharp from 'sharp';
      import * as fs from 'fs-extra';

      export const imageResize = functions.storage
      .object()
      .onFinalize(async object => {
      console.log('> > > > > > > 1.3 < < < < < < <');
      const bucket = gcs.bucket(object.bucket);
      console.log(object.name);
      const filePath = object.name;
      const fileName = filePath.split('/').pop();
      const tmpFilePath = join(tmpdir(), object.name);

      const thumbFileName = 'thumb_' + fileName;
      const tmpThumbPath = join(tmpdir(), thumbFileName);

      console.log('step 1');
      // Resizing image
      if (fileName.includes('thumb_'))
      console.log('exiting function');
      return false;

      console.log('step 2');
      console.log(`filePath: $filePath`);
      console.log(`tmpFilePath: $tmpFilePath`);
      await bucket.file(filePath).download(
      destination: tmpFilePath
      );
      console.log('step 3');
      await sharp(tmpFilePath)
      .resize(200, 200)
      .toFile(tmpThumbPath);

      await bucket.upload(tmpThumbPath,
      destination: join(dirname(filePath), thumbFileName)
      );


      UPDATE 1: added await fs.ensureDir(tmpFilePath); to ensure the filepath exists. Now getting a new error:




      Error: EINVAL: invalid argument, open '/tmp/images/1542146603970_mouse.png' at Error (native)




      UPDATE 2 SOLVED: Added a solution as an Answer below.










      share|improve this question
















      I'm trying to do a simple function that resizes a newly uploaded image in Storage. I use the following to help me do that:



      import tmpdir from 'os';
      import join, dirname from 'path';
      import * as sharp from 'sharp';
      import * as fs from 'fs-extra';


      When this code executes:



      await bucket.file(filePath).download(
      destination: tmpFilePath
      );


      I get the following error in the Google Cloud Function logs:




      Error: ENOENT: no such file or directory, open '/tmp/images/1542144115815_Emperor_penguins.jpg' at Error (native)




      Here is the full code [segment]:



      const gcs = admin.storage();
      const db = admin.firestore();

      import tmpdir from 'os';
      import join, dirname from 'path';

      import * as sharp from 'sharp';
      import * as fs from 'fs-extra';

      export const imageResize = functions.storage
      .object()
      .onFinalize(async object => {
      console.log('> > > > > > > 1.3 < < < < < < <');
      const bucket = gcs.bucket(object.bucket);
      console.log(object.name);
      const filePath = object.name;
      const fileName = filePath.split('/').pop();
      const tmpFilePath = join(tmpdir(), object.name);

      const thumbFileName = 'thumb_' + fileName;
      const tmpThumbPath = join(tmpdir(), thumbFileName);

      console.log('step 1');
      // Resizing image
      if (fileName.includes('thumb_'))
      console.log('exiting function');
      return false;

      console.log('step 2');
      console.log(`filePath: $filePath`);
      console.log(`tmpFilePath: $tmpFilePath`);
      await bucket.file(filePath).download(
      destination: tmpFilePath
      );
      console.log('step 3');
      await sharp(tmpFilePath)
      .resize(200, 200)
      .toFile(tmpThumbPath);

      await bucket.upload(tmpThumbPath,
      destination: join(dirname(filePath), thumbFileName)
      );


      UPDATE 1: added await fs.ensureDir(tmpFilePath); to ensure the filepath exists. Now getting a new error:




      Error: EINVAL: invalid argument, open '/tmp/images/1542146603970_mouse.png' at Error (native)




      UPDATE 2 SOLVED: Added a solution as an Answer below.







      node.js google-cloud-firestore google-cloud-storage google-cloud-functions






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 2:02







      Kenny

















      asked Nov 13 '18 at 21:39









      KennyKenny

      76031037




      76031037






















          2 Answers
          2






          active

          oldest

          votes


















          0














          I suspect you'd see that message because you tried to write to this path:



          /tmp/images/1542144115815_Emperor_penguins.jpg


          Without first creating the parent directory:



          /tmp/images


          You can't write a file to a local filesystem folder that doesn't exist, and it seems that the Cloud Storage SDK will not create it for you.






          share|improve this answer























          • But isn't that what this is doing, const tmpFilePath = join(tmpdir(), object.name); creating the directory? (Where object name is images/1542144115815_Emperor_penguins.jpg)

            – Kenny
            Nov 13 '18 at 21:48












          • No, that's just building a string. It has nothing to do with the filesystem yet.

            – Doug Stevenson
            Nov 13 '18 at 21:49











          • It's very similar to how it's done in this version, where the code is a little older: angularfirebase.com/lessons/…

            – Kenny
            Nov 13 '18 at 21:51











          • If you're only dealing with a single file in this function, why don't you just give it a static name/path, rather than a name derived from the path in Storage?

            – Doug Stevenson
            Nov 13 '18 at 21:51












          • The key thing you missing from that sample is the call to await fs.ensureDir(workingDir);. That creates the directory.

            – Doug Stevenson
            Nov 13 '18 at 21:54


















          0














          I changed the following code



          From



          const bucket = gcs.bucket(object.bucket);
          const filePath = object.name;
          const fileName = filePath.split('/').pop();
          const tmpFilePath = join(tmpdir(), object.name);

          const thumbFileName = 'thumb_' + fileName;
          const tmpThumbPath = join(tmpdir(), thumbFileName);


          To



          const bucket = gcs.bucket(object.bucket);
          const filePath = object.name;
          const fileName = filePath.split('/').pop();
          const thumbFileName = 'thumb_' + fileName;

          const workingDir = join(tmpdir(), `$object.name.split('/')[0]/`);//new
          const tmpFilePath = join(workingDir, fileName);
          const tmpThumbPath = join(workingDir, thumbFileName);

          await fs.ensureDir(workingDir);


          As you can see, I created a workingDir that would be shared between the paths and then ran await fs.ensureDir(workingDir); to create the path. That solved my problem.






          share|improve this answer






















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53289910%2fgoogle-cloud-function-error-enoent-no-such-file-or-directory%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            I suspect you'd see that message because you tried to write to this path:



            /tmp/images/1542144115815_Emperor_penguins.jpg


            Without first creating the parent directory:



            /tmp/images


            You can't write a file to a local filesystem folder that doesn't exist, and it seems that the Cloud Storage SDK will not create it for you.






            share|improve this answer























            • But isn't that what this is doing, const tmpFilePath = join(tmpdir(), object.name); creating the directory? (Where object name is images/1542144115815_Emperor_penguins.jpg)

              – Kenny
              Nov 13 '18 at 21:48












            • No, that's just building a string. It has nothing to do with the filesystem yet.

              – Doug Stevenson
              Nov 13 '18 at 21:49











            • It's very similar to how it's done in this version, where the code is a little older: angularfirebase.com/lessons/…

              – Kenny
              Nov 13 '18 at 21:51











            • If you're only dealing with a single file in this function, why don't you just give it a static name/path, rather than a name derived from the path in Storage?

              – Doug Stevenson
              Nov 13 '18 at 21:51












            • The key thing you missing from that sample is the call to await fs.ensureDir(workingDir);. That creates the directory.

              – Doug Stevenson
              Nov 13 '18 at 21:54















            0














            I suspect you'd see that message because you tried to write to this path:



            /tmp/images/1542144115815_Emperor_penguins.jpg


            Without first creating the parent directory:



            /tmp/images


            You can't write a file to a local filesystem folder that doesn't exist, and it seems that the Cloud Storage SDK will not create it for you.






            share|improve this answer























            • But isn't that what this is doing, const tmpFilePath = join(tmpdir(), object.name); creating the directory? (Where object name is images/1542144115815_Emperor_penguins.jpg)

              – Kenny
              Nov 13 '18 at 21:48












            • No, that's just building a string. It has nothing to do with the filesystem yet.

              – Doug Stevenson
              Nov 13 '18 at 21:49











            • It's very similar to how it's done in this version, where the code is a little older: angularfirebase.com/lessons/…

              – Kenny
              Nov 13 '18 at 21:51











            • If you're only dealing with a single file in this function, why don't you just give it a static name/path, rather than a name derived from the path in Storage?

              – Doug Stevenson
              Nov 13 '18 at 21:51












            • The key thing you missing from that sample is the call to await fs.ensureDir(workingDir);. That creates the directory.

              – Doug Stevenson
              Nov 13 '18 at 21:54













            0












            0








            0







            I suspect you'd see that message because you tried to write to this path:



            /tmp/images/1542144115815_Emperor_penguins.jpg


            Without first creating the parent directory:



            /tmp/images


            You can't write a file to a local filesystem folder that doesn't exist, and it seems that the Cloud Storage SDK will not create it for you.






            share|improve this answer













            I suspect you'd see that message because you tried to write to this path:



            /tmp/images/1542144115815_Emperor_penguins.jpg


            Without first creating the parent directory:



            /tmp/images


            You can't write a file to a local filesystem folder that doesn't exist, and it seems that the Cloud Storage SDK will not create it for you.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 13 '18 at 21:46









            Doug StevensonDoug Stevenson

            73.2k984105




            73.2k984105












            • But isn't that what this is doing, const tmpFilePath = join(tmpdir(), object.name); creating the directory? (Where object name is images/1542144115815_Emperor_penguins.jpg)

              – Kenny
              Nov 13 '18 at 21:48












            • No, that's just building a string. It has nothing to do with the filesystem yet.

              – Doug Stevenson
              Nov 13 '18 at 21:49











            • It's very similar to how it's done in this version, where the code is a little older: angularfirebase.com/lessons/…

              – Kenny
              Nov 13 '18 at 21:51











            • If you're only dealing with a single file in this function, why don't you just give it a static name/path, rather than a name derived from the path in Storage?

              – Doug Stevenson
              Nov 13 '18 at 21:51












            • The key thing you missing from that sample is the call to await fs.ensureDir(workingDir);. That creates the directory.

              – Doug Stevenson
              Nov 13 '18 at 21:54

















            • But isn't that what this is doing, const tmpFilePath = join(tmpdir(), object.name); creating the directory? (Where object name is images/1542144115815_Emperor_penguins.jpg)

              – Kenny
              Nov 13 '18 at 21:48












            • No, that's just building a string. It has nothing to do with the filesystem yet.

              – Doug Stevenson
              Nov 13 '18 at 21:49











            • It's very similar to how it's done in this version, where the code is a little older: angularfirebase.com/lessons/…

              – Kenny
              Nov 13 '18 at 21:51











            • If you're only dealing with a single file in this function, why don't you just give it a static name/path, rather than a name derived from the path in Storage?

              – Doug Stevenson
              Nov 13 '18 at 21:51












            • The key thing you missing from that sample is the call to await fs.ensureDir(workingDir);. That creates the directory.

              – Doug Stevenson
              Nov 13 '18 at 21:54
















            But isn't that what this is doing, const tmpFilePath = join(tmpdir(), object.name); creating the directory? (Where object name is images/1542144115815_Emperor_penguins.jpg)

            – Kenny
            Nov 13 '18 at 21:48






            But isn't that what this is doing, const tmpFilePath = join(tmpdir(), object.name); creating the directory? (Where object name is images/1542144115815_Emperor_penguins.jpg)

            – Kenny
            Nov 13 '18 at 21:48














            No, that's just building a string. It has nothing to do with the filesystem yet.

            – Doug Stevenson
            Nov 13 '18 at 21:49





            No, that's just building a string. It has nothing to do with the filesystem yet.

            – Doug Stevenson
            Nov 13 '18 at 21:49













            It's very similar to how it's done in this version, where the code is a little older: angularfirebase.com/lessons/…

            – Kenny
            Nov 13 '18 at 21:51





            It's very similar to how it's done in this version, where the code is a little older: angularfirebase.com/lessons/…

            – Kenny
            Nov 13 '18 at 21:51













            If you're only dealing with a single file in this function, why don't you just give it a static name/path, rather than a name derived from the path in Storage?

            – Doug Stevenson
            Nov 13 '18 at 21:51






            If you're only dealing with a single file in this function, why don't you just give it a static name/path, rather than a name derived from the path in Storage?

            – Doug Stevenson
            Nov 13 '18 at 21:51














            The key thing you missing from that sample is the call to await fs.ensureDir(workingDir);. That creates the directory.

            – Doug Stevenson
            Nov 13 '18 at 21:54





            The key thing you missing from that sample is the call to await fs.ensureDir(workingDir);. That creates the directory.

            – Doug Stevenson
            Nov 13 '18 at 21:54













            0














            I changed the following code



            From



            const bucket = gcs.bucket(object.bucket);
            const filePath = object.name;
            const fileName = filePath.split('/').pop();
            const tmpFilePath = join(tmpdir(), object.name);

            const thumbFileName = 'thumb_' + fileName;
            const tmpThumbPath = join(tmpdir(), thumbFileName);


            To



            const bucket = gcs.bucket(object.bucket);
            const filePath = object.name;
            const fileName = filePath.split('/').pop();
            const thumbFileName = 'thumb_' + fileName;

            const workingDir = join(tmpdir(), `$object.name.split('/')[0]/`);//new
            const tmpFilePath = join(workingDir, fileName);
            const tmpThumbPath = join(workingDir, thumbFileName);

            await fs.ensureDir(workingDir);


            As you can see, I created a workingDir that would be shared between the paths and then ran await fs.ensureDir(workingDir); to create the path. That solved my problem.






            share|improve this answer



























              0














              I changed the following code



              From



              const bucket = gcs.bucket(object.bucket);
              const filePath = object.name;
              const fileName = filePath.split('/').pop();
              const tmpFilePath = join(tmpdir(), object.name);

              const thumbFileName = 'thumb_' + fileName;
              const tmpThumbPath = join(tmpdir(), thumbFileName);


              To



              const bucket = gcs.bucket(object.bucket);
              const filePath = object.name;
              const fileName = filePath.split('/').pop();
              const thumbFileName = 'thumb_' + fileName;

              const workingDir = join(tmpdir(), `$object.name.split('/')[0]/`);//new
              const tmpFilePath = join(workingDir, fileName);
              const tmpThumbPath = join(workingDir, thumbFileName);

              await fs.ensureDir(workingDir);


              As you can see, I created a workingDir that would be shared between the paths and then ran await fs.ensureDir(workingDir); to create the path. That solved my problem.






              share|improve this answer

























                0












                0








                0







                I changed the following code



                From



                const bucket = gcs.bucket(object.bucket);
                const filePath = object.name;
                const fileName = filePath.split('/').pop();
                const tmpFilePath = join(tmpdir(), object.name);

                const thumbFileName = 'thumb_' + fileName;
                const tmpThumbPath = join(tmpdir(), thumbFileName);


                To



                const bucket = gcs.bucket(object.bucket);
                const filePath = object.name;
                const fileName = filePath.split('/').pop();
                const thumbFileName = 'thumb_' + fileName;

                const workingDir = join(tmpdir(), `$object.name.split('/')[0]/`);//new
                const tmpFilePath = join(workingDir, fileName);
                const tmpThumbPath = join(workingDir, thumbFileName);

                await fs.ensureDir(workingDir);


                As you can see, I created a workingDir that would be shared between the paths and then ran await fs.ensureDir(workingDir); to create the path. That solved my problem.






                share|improve this answer













                I changed the following code



                From



                const bucket = gcs.bucket(object.bucket);
                const filePath = object.name;
                const fileName = filePath.split('/').pop();
                const tmpFilePath = join(tmpdir(), object.name);

                const thumbFileName = 'thumb_' + fileName;
                const tmpThumbPath = join(tmpdir(), thumbFileName);


                To



                const bucket = gcs.bucket(object.bucket);
                const filePath = object.name;
                const fileName = filePath.split('/').pop();
                const thumbFileName = 'thumb_' + fileName;

                const workingDir = join(tmpdir(), `$object.name.split('/')[0]/`);//new
                const tmpFilePath = join(workingDir, fileName);
                const tmpThumbPath = join(workingDir, thumbFileName);

                await fs.ensureDir(workingDir);


                As you can see, I created a workingDir that would be shared between the paths and then ran await fs.ensureDir(workingDir); to create the path. That solved my problem.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 14 '18 at 2:02









                KennyKenny

                76031037




                76031037



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53289910%2fgoogle-cloud-function-error-enoent-no-such-file-or-directory%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Top Tejano songwriter Luis Silva dead of heart attack at 64

                    ReactJS Fetched API data displays live - need Data displayed static

                    政党