Solución:
Si quieres atrapar el NoSuchKey
error arrojado por createReadStream
tienes 2 opciones:
- Compruebe si existe la clave antes de leerla.
-
Detectar el error de la transmisión
Primero:
s3.getObjectMetadata(key)
.promise()
.then(() => {
// This will not throw error anymore
s3.getObject().createReadStream();
})
.catch(error => {
if (error.statusCode === 404) {
// Catching NoSuchKey
}
});
El único caso en el que no detectará el error si el archivo se eliminó en una fracción de segundo, entre la respuesta de análisis de getObjectMetadata
y corriendo createReadStream
Segundo:
s3.getObject().createReadStream().on('error', error => {
// Catching NoSuchKey & StreamContentLengthMismatch
});
Este es un enfoque más genérico y detectará todos los demás errores, como problemas de red.
Debe escuchar el error emitido antes. Su gestor de errores solo busca errores durante la parte de descompresión.
Una versión simplificada de su secuencia de comandos.
s3.getObject(params)
.createReadStream()
.on('error', (e) => {
// handle aws s3 error from createReadStream
})
.pipe(unzip)
.on('data', (data) => {
// retrieve data
})
.on('end', () => {
// stream has ended
})
.on('error', (e) => {
// handle error from unzip
});
De esta forma, no es necesario realizar una llamada adicional a AWS para averiguar si existe.
Puede escuchar eventos (como error, datos, finalización) en la transmisión que está recibiendo. Leer más sobre eventos
function getObjectStream (filePath) {
return s3.getObject({
Bucket: bucket,
Key: filePath
}).createReadStream()
}
let readStream = getObjectStream('/path/to/file.zip')
readStream.on('error', function (error) {
// Handle your error here.
})
Probado para el error “Sin clave”.
it('should not be able to get stream of unavailable object', function (done) {
let filePath="file_not_available.zip"
let readStream = s3.getObjectStream(filePath)
readStream.on('error', function (error) {
expect(error instanceof Error).to.equal(true)
expect(error.message).to.equal('The specified key does not exist.')
done()
})
})
Probado para el éxito.
it('should be able to get stream of available object', function (done) {
let filePath="test.zip"
let receivedBytes = 0
let readStream = s3.getObjectStream(filePath)
readStream.on('error', function (error) {
expect(error).to.equal(undefined)
})
readStream.on('data', function (data) {
receivedBytes += data.length
})
readStream.on('finish', function () {
expect(receivedBytes).to.equal(3774)
done()
})
})