错误callback没有用于链接然后()与ssh2-sftp客户端在node.js lambda

我对节点和lambda非常新,所以我可能会犯一些愚蠢的错误。 我创build了一个node.js aws lambda函数,它从s3事件中获取一个文件。 如果文件是gzip解压缩,则将其上传到sftp服务器,然后创build并上传一个sig文件到同一个sftp服务器。 它在一切顺利的时候起作用,但似乎并没有正确地触发错误。

sftp命令被连接在一起,所以我希望任何错误都会导致后续的失败。 例如,如果我closures了我的sftp服务器,sftp客户端将会产生一个超时错误,但是lambda永远不会看到callback错误,只会成功。 日志确实向控制台显示错误输出,但是在跟随其余的.then()项目之后,似乎使用成功callback。 连接是否被正确logging为承诺?

示例日志:

... Starting SFTP Connected to sftp, starting sftp put for lastsub2.dat file. { Error: Timed out while waiting for handshake at Timeout._onTimeout (/var/task/node_modules/ssh2/lib/client.js:687:19) at ontimeout (timers.js:386:14) at tryOnTimeout (timers.js:250:5) at Timer.listOnTimeout (timers.js:214:5) level: 'client-timeout' } 'Error occured during sftp relay.' END 

示例代码:

 console.log('Loading function'); const aws = require('aws-sdk'); const s3 = new aws.S3({ apiVersion: '2006-03-01' }); const zlib = require('zlib'); const fs = require("fs"); const connSettings = { host: 'xxx', port: '22', username: 'xxx', password: 'xxx' }; exports.handler = function (event, context, callback) { console.log('Received event:', JSON.stringify(event, null, 2)); console.log('Bucket Name: ' + event.Records[0].s3.bucket.name); console.log('Object Key: ' + decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '))); const bucket = event.Records[0].s3.bucket.name; const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); const params = { Bucket: bucket, Key: key, }; s3.getObject(params, (err, data) => { if (err) { console.log(err); const message = 'Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.'; console.log(message); callback(message); } else { if (data.ContentType == 'application/x-gzip') { console.log('CONTENT TYPE is application/x-gzip'); var dataStream = s3.getObject(params).createReadStream().pipe(zlib.Unzip()); console.log('Created unzip datastream'); console.log('Starting SFTP'); let Client = require('ssh2-sftp-client'); let sftp = new Client(); sftp.connect(connSettings) .then(console.log('Connected to sftp, starting sftp put for ' + key.replace('.gz', '.dat') + ' file.')) .then(() => { console.log('Finished sftp put for ' + key.replace('.gz', '.dat') + ' file.'); return sftp.put(dataStream, key.replace('.gz', '.dat'), true, 'utf-8'); }).then(() => { var sigFileName = key.replace('.gz', '.sig'); var sigStream = fs.createWriteStream('/tmp/' + sigFileName); sigStream.end(); console.log('Created ' + sigFileName + ' sig file.'); var readStream = fs.createReadStream('/tmp/' + sigFileName); console.log('Uploaded ' + sigFileName + ' sig file.'); return sftp.put(readStream, sigFileName, true, 'utf-8'); }).then(() => { console.log('Ended sftp connection.'); return sftp.end(); }) .then(callback(null, 'Success')) .catch ((err) => { console.log(err, 'Error occured during sftp relay.'); callback('Error', err); }); } else { callback(null, 'Uploaded file not in gzip format, will not be processed.'); } } }); }; 

你正在发生的问题正在发生,因为你没有从then()返回任何东西。 结果是每个then()立即执行而不等待任何asynchronoussftp函数返回,因为它立即parsing为undefined。

你没有提到你使用的是什么sftp库,但是假设它返回一个promise,你应该能够简单地从then()返回这些promise。

例如:

 .then(() => { console.log('Finished sftp put for ' + key.replace('.gz', '.dat') + ' file.'); // assumes stfp.put returns a promise, just return it into the chain return sftp.put(dataStream, key.replace('.gz', '.dat'), true, 'utf-8'); }) 

基于评论的编辑:

您应该能够从then()中调用callback函数。 现在在编辑中查看日志输出,这不是几乎所有你所期望的,当出现错误时 – 它跳到了这个问题上。 你正在得到控制台的输出,“连接到sftp …”,因为你打电话的方式。 代替:

 .then(console.log('Connected to sftp, starting sftp put for ' + key.replace('.gz', '.dat') + ' file.')) 

它应该可能是:

 .then(() => console.log('Connected to sftp, starting sftp put for ' + key.replace('.gz', '.dat') + ' file.')) 

你有它的方式,控制台将logging从sftp返回错误之前。