2015-05-16 18 views
6

Tôi đang cố gắng tải hình ảnh lên S3 nhưng khi tôi gọi s3.putObject (params, callback), gọi lại của tôi không bao giờ được gọi và không có lỗi nào được ghi lại.S3.putObject - gọi lại không bao giờ được gọi là

Dưới đây là các mã có liên quan:

var params = { 
    Key: key, 
    Body: imageData, 
    ContentLength: imageData.byteCount, 
    ContentType: contentType, 
}; 
this.s3.putObject(params, function(err, data) { 
    console.log('here'); 
    if (err) { 
    callback(err); 
    return; 
    } 
    callback(null, key); 
}); 

đâu params là { Key: 'e2f99bf3a321282cc7dfaef69fe8ca62.jpg', Body: {imageData parsed from request using node-multiparty}, ContentLength: 27802, ContentType: 'image/jpeg', }

Tôi đã xác minh rằng this.s3 là hợp lệ và typeof this.s3.putObject là chức năng như mong đợi.

+0

Bạn có thể nhận được một số thông tin chi tiết bằng cách cài đặt và yêu cầu mô-đun 'nock' từ npm sẽ in chính xác URL nào đang được yêu cầu. Nếu chương trình bị treo chờ đợi cuộc gọi lại, có lẽ tường lửa sẽ bỏ qua nỗ lực kết nối TCP. Bạn đã để chương trình treo trong vài phút để xem liệu nó có hết thời gian và gọi lại không? –

+0

Chương trình của bạn có được thực thi trước khi sự kiện async có thể trả về một giá trị không? Xem một chủ đề tương tự với AWS Lambda: https://stackoverflow.com/questions/28449363/why-is-this-http-request-not-working-on-aws-lambda –

Trả lời

3

Nếu mã này đang được sử dụng cho một hàm lambda bạn cần phải thêm context.done() trong hàm callback của putObject như vậy:

 s3.putObject(params, function(err, data) { 
      if (err) console.log(err, err.stack); // an error occurred 
      else  console.log(data);   // successful response 
      context.done(); 
     }); 

này buộc thực hiện để chờ cho đến khi gọi lại được lấp đầy trước nó thoát. Để làm việc này, bạn cũng sẽ cần xóa bất kỳ context.succeed hoặc context.done nào khỏi trình xử lý chính nếu bạn có một trình điều khiển đó.

+0

"ngữ cảnh" là gì trong này ... um ... bối cảnh? Nó không được khai báo ở bất kỳ nơi nào trong mã của bạn hoặc câu hỏi ban đầu. –

+0

Ah, điểm tốt @boutell. Tôi đã giả định rằng câu hỏi này được đề cập đến bằng cách sử dụng AWS Lambda, mặc dù nó không rõ ràng nói như vậy. Tôi sẽ chỉnh sửa câu trả lời của mình để phản ánh điều đó. Bối cảnh là một đối tượng cụ thể Lambda. Nếu sử dụng Lambda, một cuộc gọi đến một phương thức hoàn thiện ngữ cảnh (được thực hiện, thành công, thất bại) trong hàm gọi lại là cần thiết để cho phép nó kết thúc. Nếu đây không phải là mã Lambda, thì chương trình đang được sử dụng kết thúc trước khi hoàn thành gọi lại. – Charles

+0

Cảm ơn bạn đã làm rõ! Bạn có thể muốn viết "AWS Lambda" chỉ đơn giản bởi vì hàm lambda có ý nghĩa chung hơn. –

0

Tôi nhận được chính xác hành vi tương tự với tất cả các quyền IAM và mất một chút thời gian trước khi tôi làm việc đó.

Nếu hàm lambda của bạn chạy bên trong VPC, bạn phải tạo điểm cuối cho S3 như mô tả trong this article from AWS blog.

Nếu bạn muốn xem chi tiết hơn về nơi treo, bạn có thể sử dụng mã sau đây. Thay vì gọi lại, hãy giữ tham chiếu về yêu cầu và về cơ bản quan sát các sự kiện của nó (xem tài liệu của S3.putObjectAWS.Request).

var obj = s3.putObject(params); 
obj.on('validate',    (...args)=>{args.unshift('validate');    console.log(...args);}) 
    .on('build',    (...args)=>{args.unshift('build');    console.log(...args);}) 
    .on('sign',     (...args)=>{args.unshift('sign');     console.log(...args);}) 
    .on('send',     (...args)=>{args.unshift('send');     console.log(...args);}) 
    .on('retry',    (...args)=>{args.unshift('retry');    console.log(...args);}) 
    .on('extractError',   (...args)=>{args.unshift('extractError');   console.log(...args);}) 
    .on('extractData',   (...args)=>{args.unshift('extractData');   console.log(...args);}) 
    .on('success',    (...args)=>{args.unshift('success');    console.log(...args);}) 
    .on('error',    (...args)=>{args.unshift('error');    console.log(...args);}) 
    .on('complete',    (...args)=>{args.unshift('complete');    console.log(...args);}) 
    .on('httpHeaders',   (...args)=>{args.unshift('httpHeaders');   console.log(...args);}) 
    .on('httpData',    (...args)=>{args.unshift('httpData');    console.log(...args);}) 
    .on('httpUploadProgress', (...args)=>{args.unshift('httpUploadProgress'); console.log(...args);}) 
    .on('httpDownloadProgress', (...args)=>{args.unshift('httpDownloadProgress'); console.log(...args);}) 
    .on('httpError',   (...args)=>{args.unshift('httpError');   console.log(...args);}) 
    .on('httpDone',    (...args)=>{args.unshift('httpDone');    console.log(...args);}) 
    .send(); 

Bằng cách đó tôi đã thấy yêu cầu HTTP cơ bản đã cố gắng để đạt được các url công cộng của xô, mà là không thể từ một VPC trừ khi bạn có điểm cuối :).

Đây cũng là một bài đăng về truy cập AWS ressources từ VPC cũng từ AWS blog.

Các vấn đề liên quan