S3 потоковое с etags (узел)
Мы транслируем контент с S3 в узел, используя createReadStream()
в aws-sdk. Мы хотели бы добавить поддержку 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);
};
Я пытался прослушивать события в потоке и использовать обратные вызовы в запросе, возвращенном из getObject. Я могу получить сообщение об ошибке таким образом, но что-то еще в 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)
1 ответ
Кажется, что ошибка генерируется в потоке, и если вы слушаете AWS.Request, вы получите ошибку, но ошибка потока все еще не перехвачена.
Учти это:
s3.getObject({
Bucket: 'foo',
Key: 'bar'
}).on('error', function (err) {
console.log('Error event!');
}).createReadStream();
Это покажет "Событие ошибки!" но он также выдаст ошибку и выйдет из процесса. Это связано с тем, что поток, созданный createReadStream, также получает ошибку.
Учти это:
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 на наличие ошибок, но также и объект потока. Сначала будет напечатано "Событие ошибки!", Затем "Событие ошибки в потоке!" и процесс не выйдет.
Обратите внимание, что это:
s3.getObject({
Bucket: 'lalaland',
Key: 'blabaliets'
}).createReadStream().on('error', function (err) {
console.log('Error event on stream!');
});
Будет только печатать "Событие ошибки в потоке!" и не выход. Этот последний вариант, вероятно, то, что вам нужно: прослушивать только ошибки в потоке, а не в объекте запроса.
Чтобы вернуться к своим первоначальным намерениям; в этот момент (в сообщении об ошибке в потоке) вы хотите проверить, действительно ли это ошибка NotModified, и сделать что-то вроде res.status(304).end()
,