Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

178
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda