无法从AWS sdk [S3]中捕获错误

时间:2018-01-10 18:06:29

标签: node.js amazon-s3 aws-sdk

我试图从S3下载S3中不存在的文件。我希望在这种情况下出现错误,我也从aws-sdk中得到错误,即

** /流浪/ node_modules / AWS-SDK / LIB / request.js:31 扔错了; ^

NoSuchKey:指定的密钥不存在。**

但问题是,我无法捕捉到这个错误。如果你检查下面的代码,我的监听器request.on会被调用,当我调用reject时,promise不会从带有reject的方法downloadFontInfoFileFromS3返回。

有什么方法可以捕获错误并优雅地拒绝来自downloadFontInfoFileFromS3函数的承诺?

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
    });
}

1 个答案:

答案 0 :(得分:0)

我也遇到了这个问题。原来我没有将错误处理程序设置在正确的位置。

当前,您有:

// INCORRECT. Won't work

const download = request.createReadStream().pipe(file);

download.on('error', (error) => {
    reject(error);
});

但是实际上您需要在流上设置错误处理程序,开始管道操作之前。像这样:

// 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);

如果您在管道开始后尝试设置事件处理程序,则该错误将“绕过”您指定的任何try / catch或Promise .catch处理程序。相当令人沮丧!

请查看this GitHub issue作为另一个示例。