wake-up-neo.net

s3.getObject (). createReadStream (): Wie fange ich den Fehler ab?

Ich versuche, ein Programm zu schreiben, um eine Zip-Datei von S3 zu erhalten, zu entpacken und dann nach S3 hochzuladen. Aber ich habe zwei Ausnahmen gefunden, die ich nicht fangen kann.

1.StreamContentLengthMismatch: Stream content length mismatch. Received 980323883 of 5770104761 bytes. Dies geschieht unregelmäßig.

2.NoSuchKey: The specified key does not exist. Dies passiert, wenn ich den falschen Schlüssel eingebe.

Wenn diese beiden Ausnahmen auftreten, stürzt dieses Programm ab.

Ich möchte diese beiden Ausnahmen richtig einfangen und handhaben.

Ich möchte einen Absturz verhindern.

   const unzipUpload = () => {
        return new Promise((resolve, reject) => {
            let rStream = s3.getObject({Bucket: 'bucket', Key: 'hoge/hoge.Zip'})
                .createReadStream()
                    .pipe(unzip.Parse())
                    .on('entry', function (entry) {
                        if(entry.path.match(/__MACOSX/) == null){

                            // pause
                            if(currentFileCount - uploadedFileCount > 10) rStream.pause()

                            currentFileCount += 1
                            var fileName = entry.path;
                            let up = entry.pipe(uploadFromStream(s3,fileName))

                            up.on('uploaded', e => {
                                uploadedFileCount += 1
                                console.log(currentFileCount, uploadedFileCount)

                                //resume
                                if(currentFileCount - uploadedFileCount <= 10) rStream.resume()

                                if(uploadedFileCount === allFileCount) resolve()
                                entry.autodrain()
                            }).on('error', e => {
                                reject()
                            })
                        }

                    }).on('error', e => {
                        console.log("unzip error")
                        reject()
                    }).on('finish', e => {
                        allFileCount = currentFileCount
                    })
            rStream.on('error', e=> {
                console.log(e)
                reject(e)
            })
        })
    }

    function uploadFromStream(s3,fileName) {
        var pass = new stream.PassThrough();

        var params = {Bucket: "bucket", Key: "hoge/unzip/" + fileName, Body: pass};
        let request = s3.upload(params, function(err, data) {
            if(err) pass.emit('error')
            if(!err) pass.emit('uploaded')
        })
        request.on('httpUploadProgress', progress => {
            console.log(progress)
        })

        return pass
    }

Dies ist die Bibliothek, die ich beim Entpacken verwende . https://github.com/mhr3/unzip-stream

Hilf mir!!

15
tomoya ishizaka

Wenn Sie den von NoSuchKey ausgelösten createReadStream-Fehler abfangen möchten, haben Sie zwei Möglichkeiten:

  1. Prüfen Sie, ob der Schlüssel vorhanden ist, bevor Sie ihn lesen.
  2. Fehler vom Stream abfangen

Zuerst :

s3.getObjectMetadata(key)
  .promise()
  .then(() => {
    // This will not throw error anymore
    s3.getObject().createReadStream();
  })
  .catch(error => {
    if (error.statusCode === 404) {
      // Catching NoSuchKey
    }
  });

Der einzige Fall, in dem Sie keine Fehlermeldung erhalten, wenn die Datei in Sekundenbruchteilen gelöscht wurde, zwischen der Analyse der Antwort von getObjectMetadata und der Ausführung von createReadStream.

Zweite

s3.getObject().createReadStream().on('error', error => {
    // Catching NoSuchKey & StreamContentLengthMismatch
});

Dies ist ein generischerer Ansatz und fängt alle anderen Fehler auf, z. B. Netzwerkprobleme.

13
Vlad Holubiev

Sie müssen den ausgegebenen Fehler früher abhören. Ihr Error-Handler sucht nur während des Entpack-Teils nach Fehlern.

Eine vereinfachte Version Ihres Skripts.

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

Auf diese Weise müssen Sie AWS nicht noch einmal anrufen, um herauszufinden, ob er existiert.

2
dmo

Sie können Ereignisse (wie Fehler, Daten, Fertigstellung) im Stream abhören, den Sie zurückerhalten. Lesen Sie mehr über Ereignisse

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

Auf Fehler "Kein Schlüssel" getestet.

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

Auf Erfolg getestet.

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()
  })
})
1
Rash