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