Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

179
Visualizações
Why doesn't promise return from Lambda work while returning stream to handler for uploading to S3?

I want to return a stream from a function for the main Lambda handler to create a pipe. This works:

const { S3Client } = require("@aws-sdk/client-s3")
const { Upload } = require('@aws-sdk/lib-storage')
const stream = require('stream')
const s3Region = 'us-east-1'
const bucketname = "my_bucket"

exports.handler = function (event, context, callback) {
    let streamfrom = stream.Readable.from(["four"])
    getS3Stream()
        .then(streamto => {
            stream.pipeline(
                streamfrom,
                streamto,
                () => {
                    callback(null, { 'statusCode': 200 })
                })
        })
}

function getS3Stream() {
    return new Promise(resolve => {
        const pass = new stream.PassThrough()
        const upload = new Upload({
            client: new S3Client({ region: s3Region }),
            params: {
                Bucket: bucketname,
                Key: "test/test.txt",
                Body: pass
            }
        })
        upload.done().then((res, error) => {
            if (error) { reject(error) }
            console.log("s3 uploaded")
        })
        resolve(pass)
    })
}

But I want the handler function to return a promise instead of using a callback, at which point it no longer works:

exports.handler = async function (event, context) {
    return new Promise(resolve => {
        let streamfrom = stream.Readable.from(["five5"])
        getS3Stream()
            .then(streamto => {
                stream.pipeline(
                    streamfrom,
                    streamto,
                    () => {
                        resolve({ 'statusCode': 200 })
                    })
            })
    })
}

It returns {"statusCode":200}, but "s3 uploaded" is not printed, and the file does not appear in S3. Am I misunderstanding something about how to use promises here?

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

If you want your handler to return a Promise, you have to mark it as async.

I have not found any documentation on this but I believe the runtime caller first checks the handler definition so it know how it should call it.

Something like:

if (handler.constructor.name === 'AsyncFunction') {
   result = await handler(event, context)
   handleResult(null, result)
} else if (handler.constructor.name === 'Function') {
   handler(event, context, handleResult)
} else {}

So, going back to your original code, it can be simply

exports.handler = async function (event, context) {
  return new Promise(resolve => {
    let streamfrom = stream.Readable.from(["five5"])
    getS3Stream()
      .then(streamto => {
        stream.pipeline(
          streamfrom,
          streamto,
          () => resolve({'statusCode': 200})
        )
      })
  })
}

function getS3Stream() {
  return new Promise(resolve => {
    const pass = new stream.PassThrough()
    const upload = new Upload({
      client: new S3Client({region: s3Region}),
      params: {
        Bucket: bucketname,
        Key: "test/test.txt",
        Body: pass
      }
    })
    upload.done().then((res, error) => {
      if (error) {
        reject(error)
      }
      console.log("s3 uploaded")
      resolve(pass)
    })
  })
}
about 4 years ago · Juan Pablo Isaza Relatório

0

Inspired by this I came up with a solution that almost meets my qualifications. The function doesn't return just the stream, it also returns the promise. I am still hoping someone will come up with something that works without that crutch.

const { S3Client } = require("@aws-sdk/client-s3")
const { Upload } = require('@aws-sdk/lib-storage')

const stream = require('stream');
const s3Region = 'us-east-1'
const bucketname = "my_bucket"

exports.handler = async function (event, context) {
    return new Promise(resolve => {
        let streamfrom = stream.Readable.from(["five5"])
        getS3Stream()
        .then(({streamto, promise})=>{
            stream.pipeline(
                streamfrom,
                streamto,
                () => promise.then(()=>resolve({ 'statusCode': 200 }))        
            )
        })
    })
}

async function getS3Stream() {
    const streamto = new stream.PassThrough()
    const s3Client = new S3Client({ region: s3Region })
    const upload = new Upload({
        client: s3Client,
        params: {
            Bucket: bucketname,
            Key: "test/test.txt",
            Body: streamto
        }
    })
    let promise = upload.done()
    return({streamto,promise})
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda