I have the following piece of code: an endpoint getting the URL of an image, downloading it, resize it, saving it locally, then uploading it to a S3 bucket. Every piece of code works fine on it's own.
// Post a URL of a pic and get a URL of its thumb on AWS S3
router.post("/", (req, res) => {
const url = req.body.url;
const tempPath = './public/uploads/';
const tempFileName = uuidv1();
const createThumbPic = async () => {
const tempURL = tempPath + tempFileName;
jimp.read(url, async (err, img) => {
if (err) {
res.status(400).json({
error: `${err})`,
});
return;
}
img.resize(120, 120)
.quality(60)
.write(tempURL);
});
return tempURL;
}
const uploadThumbnailToS3 = async () => {
const tempURLThumb = await createThumbPic();
const file = await fs.readFileSync(tempURLThumb);
const params = {
Bucket: process.env.S3_BUCKET_ID,
Key: tempFileName,
Body: file
};
// Uploading files to the bucket
const fileUrlOns3 = await s3.upload(params, function (err, data) {
if (err) {
res.status(400).json({ error: err });
}
res.status(201).json({ thumbUrl: resData });
return data.Location;
});
return fileUrlOns3;
}
// Execute Code and respond to client
uploadThumbnailToS3().catch((err) => {
res.status(400).json({ error: err });
});
});
the Error I am getting back from this endpoint:
{
"error": {
"errno": -2,
"syscall": "open",
"code": "ENOENT",
"path": "./public/uploads/imagefiletemp.jpg"
}
}
The problem comes from the follwing to lines: It seems that fs.readFileSync
runs before that createThumbPic()
is totally finished. Hence that the readFileSync doesn't find the file it should read, and throw that error back.
const tempURLThumb = await createThumbPic();
const file = await fs.readFileSync(tempURLThumb);
Somehow I know that createThumbPic
return tempURLThumb
before that the fiel is finished, as I get the response in postman, than 1 sec later I see the file appearing in my directory.
const createThumbPic = async () => {
const tempURL = tempPath + tempFileName;
jimp.read(url, async (err, img) => {
if (err) {
res.status(400).json({
error: `${err})`,
});
return;
}
img.resize(120, 120)
.quality(60)
.write(tempURL);
});
return tempURL;
}
How to make createThumbPic
wait until img.resize
is completely finished before returning tempURL?
I tried my best learning ASYNC/AWAIT, and thought I had figured, but it seems like something is still off in my code. Any tip?