2

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

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) 

回答

2

这似乎错误是在流抛出,如果你在听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()