【问题标题】:Handling aws-sdk bucket creation requests nodejs express处理 aws-sdk 存储桶创建请求 nodejs express
【发布时间】:2021-05-12 13:01:39
【问题描述】:

我有以下代码。主要目的是通过 aws-sdk 创建一个存储桶,并在成功的情况下为相关条目生成数据库记录。但是有几个问题

const AWS  = require('aws-sdk');
const router = require('express').Router();

const Bucket = require("../../../models/bucket_bucket");

const { v4: uuidv4 } = require('uuid');

require('dotenv').config();

AWS.config.logger = console;

s3 = new AWS.S3({
    // apiVersion: '2006-03-01',
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    region: process.env.AWS_REGION
});

// Accepts Bucket Name, Bucket Created User/ Belonging Organization
router.post('/create', (req, res, next)=>{

    var requestBucketParams = {
        Bucket: req.body.bucket
    }

    var isBucketCreationSuccess = false;

    var createRequestBucketPromise = s3.createBucket(requestBucketParams).promise();
    var createDeliveryBucketPromise = s3.createBucket(deliveryBucketParams).promise();

    createRequestBucketPromise.then((data)=>{
        isBucketCreationSuccess = true;
    }).catch((err)=>{
        res.send({
            message: "error while creating the bucket",
            description: err.message
        });
    });
    
    console.log(isBucketCreationSuccess);

        
    if(isBucketCreationSuccess){
        Bucket.create({
            bucketId: uuidv4(),
            name: req.body.bucket,
            bucket_url: "http://" + req.body.bucket + ".s3.amazonaws.com",
        }).then(bucket=>{
            res.send({
                url: "http://" + req.body.bucket + ".s3.amazonaws.com",
            })
        }).catch(err=>{
            res.send({
                message: err.message
            })
        })
    }else{
        res.send({
            message: "Database record creation failed"
        })
    }

});

所以我有两个问题(请多多包涵,我对nodejs不太熟悉)

  1. isBucketCreationSuccess 始终是 false 无论我如何尝试设置它。我确实相信这与异步有关。但它不起作用
  2. 这会产生以下错误
(node:25293) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
   at ServerResponse.setHeader (_http_outgoing.js:543:11)
   at ServerResponse.header (/home/caesar/Workspace/res-s3/res-s3-backend/node_modules/express/lib/response.js:771:10)
   at ServerResponse.send (/home/caesar/Workspace/res-s3/res-s3-backend/node_modules/express/lib/response.js:170:12)
   at ServerResponse.json (/home/caesar/Workspace/res-s3/res-s3-backend/node_modules/express/lib/response.js:267:15)
   at ServerResponse.send (/home/caesar/Workspace/res-s3/res-s3-backend/node_modules/express/lib/response.js:158:21)
   at /home/caesar/Workspace/res-s3/res-s3-backend/routes/api/bucket/index.js:54:13
   at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:25293) 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:25293) [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.
[AWS s3 409 2.197s 0 retries] createBucket({
 Bucket: 'delivery-bucket-1',
 CreateBucketConfiguration: { LocationConstraint: 'eu-west-1' }
})

【问题讨论】:

  • 我很好奇,为什么要动态创建 S3 Buckets?它相当奇怪。可以分享一下用例吗?
  • 这是用于管理基于组织的存储桶。这样上传的文件可以只为所需的组织集群,如果我们需要访问限制,我们可以基于创建 IAM 来实施它们
  • 好吧,这是有道理的,但请记住,S3 存储桶名称应该是全球唯一的,即所有 aws s3 用户的唯一名称。因此,要么实现命名冲突的错误处理程序,要么以不会导致命名冲突的方式创建名称

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


【解决方案1】:

您面临的问题与 Nodejs 无关。我建议刷新你对PromiseAsync/Await的了解

您共享的代码似乎不完整。我将尝试用您分享的内容来解释这个想法。

then/catch 之外的代码语句同步执行。

createRequestBucketPromise.then((data)=>{
  isBucketCreationSuccess = true;
})
.catch((err)=>{
  res.send({
    message: "error while creating the bucket",
    description: err.message
  });
});

// This will get executed before above promise handler
console.log(isBucketCreationSuccess);

下面显示的承诺没有导致警告的错误处理程序

var createDeliveryBucketPromise = s3.createBucket(deliveryBucketParams).promise();

你可以这样做来解决问题,但我推荐第二种选择,即使用Async

使用承诺

router.post('/create', (req, res, next)=>{
    // const or let is prefered over var
    const requestBucketParams = {
        Bucket: req.body.bucket
    },
    bucketUrl = `https://${req.body.bucket}.s3.amazonaws.com`;

    return s3.createBucket(requestBucketParams).promise()
    .then((data) => {
        return Bucket.create({
            bucketId: uuidv4(),
            name: req.body.bucket,
            bucket_url: bucketUrl,
        });
    })
    .then((bucket) => {
        return res.send({
            url: bucketUrl,
        });
    })
    .catch((err)=>{
        // try to differentiate between aws error and you database error
        // and respond. There are multiple ways to achieve that
    });
});

使用异步/等待

router.post('/create', async (req, res, next) => {
    // const or let is prefered over var
    const requestBucketParams = {
        Bucket: req.body.bucket
    },
    bucketUrl = `https://${req.body.bucket}.s3.amazonaws.com`;

    try {
        await s3.createBucket(requestBucketParams).promise();
    } catch (err) {
        return res.send({
            message: "error while creating the bucket",
            description: err.message
        });
    }
    
    try{
        await Bucket.create({
            bucketId: uuidv4(),
            name: req.body.bucket,
            bucket_url: bucketUrl,
        });
    } catch (err) {
        return res.send({
            message: "Database record creation failed"
        });
    }

    return res.send({
        url: bucketUrl,
    });
});

【讨论】:

  • 谢谢我遵循了 aync/await 的方式。但现在我收到以下错误。 ``` SyntaxError: await 仅在异步函数中有效 ```
  • 确保将处理函数定义为异步,即async (req, res, next)
  • 谢谢它会工作。关于如何处理(2)中指定的错误的任何想法
  • 您显示的错误是由于2个问题1)没有错误处理程序的承诺,2)多次执行res.send
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 2021-12-26
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
  • 2015-04-05
相关资源
最近更新 更多