s3stream与etags(节点)

我们使用aws-sdk中的createReadStream()从S3节点中传输内容。 我们想添加etag支持。 如果我们从客户端添加'If-None-Match'头部,s3会抛出NotModified作为我似乎无法处理的错误。

 retrieveFile = function(req, res) { var s3 = new AWS.S3(); var params = { Bucket: bucket, key: key }; if (req.get('If-None-Match')) { params.IfNoneMatch = req.get('If-None-Match'); } return s3.getObject(params).on('httpHeaders', function(statusCode, headers) { if (headers.etag) { res.set('etag', headers.etag); } if (headers['content-length']) { return res.set('content-length', headers['content-length']); } }).createReadStream().pipe(res); }; 

我试着在stream上使用从getObject返回的请求上的callback来监听事件。 我可以通过这种方式获取错误消息,但是aws-sdk中的其他内容似乎正在杀死我的进程。

 /Projects/my-app/node_modules/aws-sdk/lib/request.js:31 throw err; ^ NotModified: null at Request.extractError (/Projects/my-app/node_modules/aws-sdk/lib/services/s3.js:519:35) at Request.callListeners (/Projects/my-app/node_modules/aws-sdk/lib/sequential_executor.js:105:20) at Request.emit (/Projects/my-app/node_modules/aws-sdk/lib/sequential_executor.js:77:10) at Request.emit (/Projects/my-app/node_modules/aws-sdk/lib/request.js:673:14) at Request.transition (/Projects/my-app/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/Projects/my-app/node_modules/aws-sdk/lib/state_machine.js:14:12) at /Projects/my-app/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request.<anonymous> (/Projects/my-app/node_modules/aws-sdk/lib/request.js:38:9) at Request.<anonymous> (/Projects/my-app/node_modules/aws-sdk/lib/request.js:675:12) at Request.callListeners (/Projects/my-app/node_modules/aws-sdk/lib/sequential_executor.js:115:18) at Request.emit (/Projects/my-app/node_modules/aws-sdk/lib/sequential_executor.js:77:10) at Request.emit (/Projects/my-app/node_modules/aws-sdk/lib/request.js:673:14) at Request.transition (/Projects/my-app/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/Projects/my-app/node_modules/aws-sdk/lib/state_machine.js:14:12) at /Projects/my-app/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request.<anonymous> (/Projects/my-app/node_modules/aws-sdk/lib/request.js:38:9) at Request.<anonymous> (/Projects/my-app/node_modules/aws-sdk/lib/request.js:675:12) at Request.callListeners (/Projects/my-app/node_modules/aws-sdk/lib/sequential_executor.js:115:18) at callNextListener (/Projects/my-app/node_modules/aws-sdk/lib/sequential_executor.js:95:12) at IncomingMessage.onEnd (/Projects/my-app/node_modules/aws-sdk/lib/event_listeners.js:244:11) at emitNone (events.js:91:20) at IncomingMessage.emit (events.js:185:7) at endReadableNT (_stream_readable.js:974:12) at _combinedTickCallback (internal/process/next_tick.js:74:11) at process._tickDomainCallback (internal/process/next_tick.js:122:9) 

看起来错误是在stream上抛出,如果你正在监听AWS.Request,你会收到一个错误,但是stream错误仍然没有被捕获。

考虑一下:

 s3.getObject({ Bucket: 'foo', Key: 'bar' }).on('error', function (err) { console.log('Error event!'); }).createReadStream(); 

这将显示“错误事件! 但它也会抛出一个错误并退出进程。 这是因为createReadStream创build的stream也收到错误。

考虑一下:

 s3.getObject({ Bucket: 'lalaland', Key: 'blabaliets' }).on('error', function (err) { console.log('Error event!'); }).createReadStream().on('error', function (err) { console.log('Error event on stream!'); }); 

它将在AWS.Request对象上侦听错误, 还会在stream对象上侦听。 这将首先打印“错误事件!”,然后“错误事件在stream! 并且该进程将不会退出。

请注意这一点:

 s3.getObject({ Bucket: 'lalaland', Key: 'blabaliets' }).createReadStream().on('error', function (err) { console.log('Error event on stream!'); }); 

打印“错误事件在stream! 而不是退出。 这最后一个选项可能是你想要的:只听stream而不是请求对象上的错误。

回到你的初衷; 在这一点上(在stream上的错误),你想检查它是否确实是一个NotModified错误,并做类似res.status(304).end()