Functions-samples: Error: read ECONNRESET when resizing image in Storage

Created on 22 Mar 2017  路  6Comments  路  Source: firebase/functions-samples

I'd like to resize an image stored in Firebase Storage with Firebase Functions.

Based on this example : https://github.com/firebase/functions-samples/blob/master/quickstarts/thumbnails/functions/index.js I try to write a function triggered by a Database event.

Here is the most interesting part of the code :

const gcs = require('@google-cloud/storage')();

...

const bucket = gcs.bucket('...appspot.com');
const originalFilepath = myObject.picture1Url;
const tempFilePath = '/tmp/myThumbnail';

console.log('1');

return bucket
    .file(originalFilepath)
    .download({
        destination: tempFilePath
    })
    .then(() => {

        console.log('2');

    });

Everything looks fine to me. However the code never go to the console.log('2'); and I get this error :

Error: read ECONNRESET
    at exports._errnoException (util.js:1026:11)
    at TCP.onread (net.js:569:26)

Does somebody know what could be the error?

Thank you

Most helpful comment

Yes the issue is what @ahaverty described.

When you do this:

createThumbnail(1, ...);
createThumbnail(2, ...);
createThumbnail(3, ...);
...
return;

You are starting 3 asynchronous processes but you are returning right away. Therefore the instance gets shut down and your 3 createThumbnail don;t have time to complete.

Each of these returns a Promise. What you need to do is this instead:

const listOfAsyncJobs = [];
listOfAsyncJobs.push(createThumbnail(1, ...));
listOfAsyncJobs.push(createThumbnail(2, ...));
listOfAsyncJobs.push(createThumbnail(3, ...));
...
return Promise.all(listOfAsyncJobs); // This will ensure we wait for the end of the three aync tasks above.

All 6 comments

I got an econn error with my realtime database function, perhaps my fix could help you debug your issue? (See example of logs occuring after function terminates: https://github.com/firebase/firebase-functions/issues/18#issuecomment-288375709

As @ahaverty said can you make sure you return a Promise correctly in your code. From your snippet your code looks OK though but it's missing some parts of it we can't be sure.

Thank guys, you are right. I did some test and the problem really seems to be a problem with a return.

I don't really understand when I have to return something. I want to do something like this :

exports.myFunction =
    functions
    .database
    .ref('...')
    .onWrite(event => {

        ...

        // Create thumbnails
        createThumbnail(1, ...);
        createThumbnail(2, ...);
        createThumbnail(3, ...);

         ...

        return; // <- Is this necessary ?
    });

function createThumbnail(...) {

    ...

    return bucket
        .file(originalFilepath)
        .download({
            destination: tempFilePath
        })
        .then(() => {

            ...

            // Generate a thumbnail using ImageMagick.
            return spawn('convert', [tempFilePath, '-thumbnail', dimension + 'x' + dimension + '>', tempFilePath])
                .then(() => {

                    ....

                    // Uploading the thumbnail.
                    return bucket.upload(tempFilePath, {
                            destination: thumbnailUrl
                        })
                        .then(() => {

                              ...

                            // Save thumbnailUrl in database
                            return admin.database().ref(...).set(thumbnailUrl);
                        });
                });
        });
}

This code doesn't work. I tried to remove some of these return but either I have a read ECONNRESET or a TimeOut.

If you can give me any advice, I'd be very thankful

Yes the issue is what @ahaverty described.

When you do this:

createThumbnail(1, ...);
createThumbnail(2, ...);
createThumbnail(3, ...);
...
return;

You are starting 3 asynchronous processes but you are returning right away. Therefore the instance gets shut down and your 3 createThumbnail don;t have time to complete.

Each of these returns a Promise. What you need to do is this instead:

const listOfAsyncJobs = [];
listOfAsyncJobs.push(createThumbnail(1, ...));
listOfAsyncJobs.push(createThumbnail(2, ...));
listOfAsyncJobs.push(createThumbnail(3, ...));
...
return Promise.all(listOfAsyncJobs); // This will ensure we wait for the end of the three aync tasks above.

PS: I'll also reply on your Stack Overflow post.

Thanks a lot. You have saved my day !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MalikFaizanZafar picture MalikFaizanZafar  路  4Comments

abhilash1in picture abhilash1in  路  4Comments

rodrigoreal picture rodrigoreal  路  5Comments

palimad picture palimad  路  3Comments

blaforet picture blaforet  路  3Comments