'Not able to catch error from AWS sdk [S3]
Im trying to download a file from S3 which doesn't exist on S3. I expect a error in this scenario and im also getting that error from aws-sdk i.e.
**/vagrant/node_modules/aws-sdk/lib/request.js:31 throw err; ^
NoSuchKey: The specified key does not exist.**
But the issue is, im not able to catch this error. If you check the code below, my listener request.on gets called and when i call reject in that the promise doesn't return from method downloadFontInfoFileFromS3 with reject.
Is there any way i can catch the error and gracefully reject the promise from downloadFontInfoFileFromS3 function?
downloadFontInfoFileFromS3(fileKey) {
return new Promise((resolve, reject) => {
const sThree = new awsSDK.S3();
const options = {
Bucket: awsConf.bucket,
Key: fileKey,
};
const downloadFilePath = SOME_PATH
const file = fs.createWriteStream(downloadFilePath);
const request = sThree.getObject(options);
const download = request
.createReadStream().pipe(file);
// called when error in aws-sdk
request.on('error', (error) => {
logger.error('Failed to download file from S3:', error.message);
reject(error);
});
download.on('error', (error) => {
reject(error);
});
download.on('finish', () => {
resolve(downloadFilePath);
});
// the synchronous code that we want to catch thrown errors on
});
}
Solution 1:[1]
I ran into this issue as well. Turns out I wasn't setting the error handler in the correct place.
Currently, you have:
// INCORRECT. Won't work
const download = request.createReadStream().pipe(file);
download.on('error', (error) => {
reject(error);
});
But you actually need to set the error handler on the stream, before you begin piping. Like this:
// Correct!
const download = request.createReadStream(); // notice the `.pipe()` has been removed
download.on('error', (error) => {
reject(error);
});
// now you can begin piping to the file
requestStream.pipe(file);
If you try setting the event handler after the pipe has begun, the error will "bypass" any try/catch or Promise .catch handlers you specify. Quite frustrating!
Check out this GitHub issue for another example.
Solution 2:[2]
const data = s3.getObject({ Bucket: process.env.AWS_BUCKET_NAME, Key: url }).createReadStream();
data.on("error", (err) => {
if (err)
return next(customError("Invalid Url", 400));
});
data.pipe(res);
Right Because Error is occourd when data in pipe.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jknotek |
| Solution 2 | Aadarsh Kumar |
