2

I am trying to take an image URL using express in Typescript, filter it and send the image back as response. Here is the endpoint:

app.get("/filteredimage/", async (req, res) =>{
try{
  let {image_url} = req.query;
  if(!image_url){
    return res.status(400).send("bad request!");
  }
  console.log(image_url);
  const path = await filterImageFromURL(image_url);
  res.sendFile(path);
  res.on('finish', () => deleteLocalFiles([path]));
} catch {
  return res.status(500).send({error: 'Unable to process your request'});
}
});

the filter image url function is as:

export async function filterImageFromURL(inputURL: string): Promise<string>{
return new Promise( async resolve => {
    const photo = await Jimp.read(inputURL);
    const outpath = '/tmp/filtered.'+Math.floor(Math.random() * 2000)+'.jpg';
    await photo
    .resize(256, 256) // resize
    .quality(60) // set JPEG quality
    .greyscale() // set greyscale
    .write(__dirname+outpath, (img)=>{
        resolve(__dirname+outpath);
    });
});
}

But on hitting the endpoint I get the below error:

(node:23042) UnhandledPromiseRejectionWarning: Error: Could not find MIME for Buffer <null>
at Jimp.parseBitmap (/home/hades/udacity/cloud-developer/course-02/project/image-filter-starter-code/node_modules/@jimp/core/src/utils/image-bitmap.js:73:15)
at Jimp.call [as parseBitmap] (/home/hades/udacity/cloud-developer/course-02/project/image-filter-starter-code/node_modules/@jimp/core/src/index.js:395:17)
at parseBitmap (/home/hades/udacity/cloud-developer/course-02/project/image-filter-starter-code/node_modules/@jimp/core/src/index.js:339:14)
at cb (/home/hades/udacity/cloud-developer/course-02/project/image-filter-starter-code/node_modules/@jimp/core/src/index.js:68:14)
at cb (/home/hades/udacity/cloud-developer/course-02/project/image-filter-starter-code/node_modules/@jimp/core/src/request.js:47:9)
at IncomingMessage.<anonymous> (/home/hades/udacity/cloud-developer/course-02/project/image-filter-starter-code/node_modules/phin/lib/phin.compiled.js:1:2038)
at IncomingMessage.emit (events.js:322:22)
at endReadableNT (_stream_readable.js:1187:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
(node:23042) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error 
originated either by throwing inside of an async function without a catch block, or by 
rejecting a promise which was not handled with .catch(). To terminate the node process on 
unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see 
https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:23042) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In 
the future, promise rejections that are not handled will terminate the Node.js process with 
a non-zero exit code.

Tried adding try-catch blocks in both functions but to no luck. What am I missing?

4 Answers4

2

I am doing the same course, and the problem is, that the sample picture (https://timedotcom.files.wordpress.com/2019/03/kitten-report.jpg) no longer exists. A dapper error handling requires to modify the provided util code:

export async function filterImageFromURL(inputURL: string): Promise<string> {
    return new Promise((resolve, reject) => {
        Jimp.read(inputURL).then(photo => {
            const outpath = '/tmp/filtered.' + Math.floor(Math.random() * 2000) + '.jpg';
            photo
                .resize(256, 256) // resize
                .quality(60) // set JPEG quality
                .greyscale() // set greyscale
                .write(__dirname + outpath, (img) => {
                    resolve(__dirname + outpath);
                });
        }).catch(err => {
            console.error(err);
            reject("Could not read image.");
        })
    });
}

With this modification, you can react on this error in your code fragment.

Jan
  • 2,060
  • 2
  • 29
  • 34
0

Looks like error is not caught when Jimp.read() call is made.

Please try the below snippet.

    return new Promise(async (resolve, reject) => {
        try {
            const photo = await Jimp.read(inputURL);
            const outpath = '/tmp/filtered.' + Math.floor(Math.random() * 2000) + '.jpg';
            await photo
                .resize(256, 256) // resize
                .quality(60) // set JPEG quality
                .greyscale() // set greyscale
                .write(__dirname + outpath, (img) => {
                    resolve(__dirname + outpath);
                });

        } catch (error) {
            reject(error)
        }
    });
}
Kiran
  • 54
  • 3
0

I'm in the same course and I face the same issue. In my case I haven't apply or need to apply any modifications in the code. I'd just add a log to see the input URL that I was using in the request and I'd realized that I was sending the image URL without the extension of the image, like this:

curl http://localhost:8082/filteredimage?image_url=https://image.shutterstock.com/image-photo/diverse-amazon-forest-seen-above-600w-2072628056

Then I just fix the URL to this:

curl http://localhost:8082/filteredimage?image_url=https://image.shutterstock.com/image-photo/diverse-amazon-forest-seen-above-600w-2072628056.jpg

by adding the .jpg at the end and it worked. maybe you are having the same issue.

Alter
  • 903
  • 1
  • 11
  • 27
-2

I think I found the solution. At least it worked for me:

return new Promise(async (resolve, reject) => {
    try {
        const photo = await Jimp.read(inputURL);
        const outpath = '/tmp/filtered.' + Math.floor(Math.random() * 2000) + '.jpg';
        await photo
            .resize(256, 256) // resize
            .quality(60) // set JPEG quality
            .greyscale() // set greyscale
            .write(__dirname + outpath, (img) => {
                resolve(__dirname + outpath);
            });

    } catch (error) {
                    const photo = await Jimp.read(inputURL);
        const outpath = '/tmp/filtered.' + Math.floor(Math.random() * 2000) + '.jpg';
        await photo
            .resize(256, 256) // resize
            .quality(60) // set JPEG quality
            .greyscale() // set greyscale
            .write(__dirname + outpath, (img) => {
                resolve(__dirname + outpath);
            });
    }
});

When it catches the error, the code will run again without errors.